GMSWarehouse.cs
1using System;
2 using System.IO;
3 using GAMS;
4 
5 namespace Warehouse
6 {
15  class Warehouse
16  {
17  private static int status = 0;
18  private static string statusString = string.Empty;
19  private static void SolveWarehouse(GAMSWorkspace gmsWS, int NumberOfWarehouses, GAMSDatabase result, Object dbMutex)
20  {
21  GAMSJob gmsJ = gmsWS.AddJobFromString(GetModelText());
22  try
23  {
24  // instantiate GAMSOptions and define some scalars
25  GAMSOptions gmsOpt = gmsWS.AddOptions();
26  gmsOpt.AllModelTypes = "cplex";
27  gmsOpt.Defines.Add("Warehouse", NumberOfWarehouses.ToString());
28  gmsOpt.Defines.Add("Store", "65");
29  gmsOpt.Defines.Add("fixed", "22");
30  gmsOpt.Defines.Add("disaggregate", "0");
31  gmsOpt.OptCR = 0.0; // Solve to optimality
32 
33  // create a GAMSJob from string and write results to the result database
34  gmsJ.Run(gmsOpt);
35 
36  // need to lock database write operations
37  lock (dbMutex)
38  result.GetParameter("objrep").AddRecord(NumberOfWarehouses.ToString()).Value = gmsJ.OutDB.GetVariable("obj").FindRecord().Level;
39 
40  foreach (GAMSVariableRecord supplyRec in gmsJ.OutDB.GetVariable("supply"))
41  if (supplyRec.Level > 0.5)
42  lock (dbMutex)
43  result.GetSet("supplyMap").AddRecord(NumberOfWarehouses.ToString(), supplyRec.Key(0), supplyRec.Key(1));
44  }
45  catch (GAMSExceptionExecution e)
46  {
47  // Check if we see a User triggered abort and look for the user defined result
48  if (e.eRC == GAMSExitCode.ExecutionError)
49  lock (dbMutex)
50  statusString = gmsJ.OutDB.GetSet("res").FindRecord(gmsJ.OutDB.GetSet("ares").FirstRecord().Key(0)).Text;
51  lock (dbMutex)
52  status = e.iRC;
53  }
54  catch (GAMSException e)
55  {
56  Console.WriteLine(e.Message);
57  lock (dbMutex)
58  status = -1;
59  }
60  catch (Exception e)
61  {
62  Console.WriteLine(e.Message);
63  lock (dbMutex)
64  status = -2;
65  }
66  }
67 
68  static void Main(string[] args)
69  {
70  GAMSWorkspace gmsWS;
71  if (Environment.GetCommandLineArgs().Length > 1)
72  gmsWS = new GAMSWorkspace(systemDirectory: Environment.GetCommandLineArgs()[1]);
73  else
74  gmsWS = new GAMSWorkspace();
75 
76  // create a GAMSDatabase for the results
77  GAMSDatabase resultDB = gmsWS.AddDatabase();
78  resultDB.AddParameter("objrep",1,"Objective value");
79  resultDB.AddSet("supplyMap",3,"Supply connection with level");
80 
81  try
82  {
83  // run multiple parallel jobs
84  Object dbLock = new Object();
85  System.Threading.Tasks.Parallel.For(10, 22, delegate(int i) { SolveWarehouse(gmsWS, i, resultDB, dbLock); });
86  if (status > 0)
87  {
88  throw new GAMSExceptionExecution("Error when running GAMS: " + (GAMSExitCode)status + " " + statusString, status);
89  }
90  else if (status == -1)
91  {
92  throw new GAMSException("Error in GAMS API");
93  }
94  else if (status == -2)
95  {
96  throw new Exception();
97  }
98  // export the result database to a GDX file
99  resultDB.Export("\\tmp\\result.gdx");
100  }
101  catch (GAMSException ex)
102  {
103  Console.WriteLine("GAMSException occured: " + ex.Message);
104  }
105  catch (System.Exception ex)
106  {
107  Console.WriteLine(ex.Message);
108  }
109  finally
110  {
111  resultDB.Dispose();
112  }
113 
114  Environment.ExitCode = status;
115  }
116 
117  static String GetModelText()
118  {
119  String model = @"
120 $title Warehouse.gms
121 
122 $eolcom //
123 $SetDDList warehouse store fixed disaggregate // acceptable defines
124 $if not set warehouse $set warehouse 10
125 $if not set store $set store 50
126 $if not set fixed $set fixed 20
127 $if not set disaggregate $set disaggregate 1 // indicator for tighter bigM constraint
128 $ife %store%<=%warehouse% $abort Increase number of stores (>%warehouse)
129 
130 set res respond codes / 0 Normal
131  1 License Error
132  2 No solution
133  3 Other Error /
134  ares(res) / 3 /;
135 
136 Sets Warehouse /w1*w%warehouse% /
137  Store /s1*s%store% /
138 Alias (Warehouse,w), (Store,s);
139 Scalar
140  fixed fixed cost for opening a warehouse / %fixed% /
141 Parameter
142  capacity(WareHouse)
143  supplyCost(Store,Warehouse);
144 
145 $eval storeDIVwarehouse trunc(card(store)/card(warehouse))
146 capacity(w) = %storeDIVwarehouse% + mod(ord(w),%storeDIVwarehouse%);
147 supplyCost(s,w) = 1+mod(ord(s)+10*ord(w), 100);
148 
149 Variables
150  open(Warehouse)
151  supply(Store,Warehouse)
152  obj;
153 Binary variables open, supply;
154 
155 Equations
156  defobj
157  oneWarehouse(s)
158  defopen(w);
159 
160 defobj.. obj =e= sum(w, fixed*open(w)) + sum((w,s), supplyCost(s,w)*supply(s,w));
161 
162 oneWarehouse(s).. sum(w, supply(s,w)) =e= 1;
163 
164 defopen(w).. sum(s, supply(s,w)) =l= open(w)*capacity(w);
165 
166 $ifthen %disaggregate%==1
167 Equations
168  defopen2(s,w);
169 defopen2(s,w).. supply(s,w) =l= open(w);
170 $endif
171 
172 model distrib /all/;
173 solve distrib min obj using mip;
174 
175 $macro setResult(n) option clear=ares; ares(n) = yes;
176 if (distrib.modelstat=%ModelStat.LicensingProblem% or
177  distrib.solvestat=%Solvestat.LicensingProblems%,
178  setResult('1');
179  abort 'License Error';
180 );
181 if (distrib.solvestat<>%SolveStat.NormalCompletion% or
182  distrib.modelstat<>%ModelStat.Optimal% and
183  distrib.modelstat<>%ModelStat.IntegerSolution%,
184  setResult('2');
185  abort 'No solution';
186 );
187 setResult('0');
188 ";
189 
190  return model;
191  }
192  }
193 }
string Key(int index)
new GAMSSetRecord AddRecord(params string[] keys)
Dictionary< string, string > Defines
new GAMSParameterRecord AddRecord(params string[] keys)
GAMSDatabase OutDB
GAMSParameter GetParameter(string parameterIdentifier)
new GAMSVariableRecord FindRecord(params string[] keys)
GAMSOptions AddOptions(GAMSOptions optFrom=null)
GAMSExitCode
GAMSSet GetSet(string setIdentifier)
new GAMSSetRecord FirstRecord()
GAMSVariable GetVariable(string variableIdentifier)
GAMSJob AddJobFromString(string gamsSource, GAMSCheckpoint checkpoint=null, string jobName=null)
void Export(string filePath=null)
GAMSParameter AddParameter(string identifier, int dimension, string explanatoryText="")
new GAMSSetRecord FindRecord(params string[] keys)
void Run(GAMSOptions gamsOptions=null, GAMSCheckpoint checkpoint=null, TextWriter output=null, Boolean createOutDB=true)
GAMSDatabase AddDatabase(string databaseName=null, string inModelName=null)
GAMSSet AddSet(string identifier, int dimension, string explanatoryText="", SetType setType=SetType.multi)