Loading...
Searching...
No Matches
warehouse.cpp
Go to the documentation of this file.
1
25#include <iostream>
26#include <fstream>
27#include <mutex>
28#include <thread>
29#include "gams.h"
30
31using namespace gams;
32using namespace std;
33
34static int status;
35static string statusString;
36
39{
40 return "$title Warehouse.gms \n"
41 " \n"
42 "$eolcom // \n"
43 "$SetDDList warehouse store fixed disaggregate // acceptable defines \n"
44 "$if not set warehouse $set warehouse 10 \n"
45 "$if not set store $set store 50 \n"
46 "$if not set fixed $set fixed 20 \n"
47 "$if not set disaggregate $set disaggregate 1 // indicator for tighter bigM constraint \n"
48 "$ife %store%<=%warehouse% $abort Increase number of stores (>%warehouse) \n"
49 " \n"
50 "set res respond codes / 0 Normal \n"
51 " 1 License Error \n"
52 " 2 No solution \n"
53 " 3 Other Error / \n"
54 " ares(res) / 3 /; \n"
55 " \n"
56 "Sets Warehouse /w1*w%warehouse% / \n"
57 " Store /s1*s%store% / \n"
58 "Alias (Warehouse,w), (Store,s); \n"
59 "Scalar \n"
60 " fixed fixed cost for opening a warehouse / %fixed% / \n"
61 "Parameter \n"
62 " capacity(WareHouse) \n"
63 " supplyCost(Store,Warehouse); \n"
64 " \n"
65 "$eval storeDIVwarehouse trunc(card(store)/card(warehouse)) \n"
66 "capacity(w) = %storeDIVwarehouse% + mod(ord(w),%storeDIVwarehouse%); \n"
67 "supplyCost(s,w) = 1+mod(ord(s)+10*ord(w), 100); \n"
68 " \n"
69 "Variables \n"
70 " open(Warehouse) \n"
71 " supply(Store,Warehouse) \n"
72 " obj; \n"
73 "Binary variables open, supply; \n"
74 " \n"
75 "Equations \n"
76 " defobj \n"
77 " oneWarehouse(s) \n"
78 " defopen(w); \n"
79 " \n"
80 "defobj.. obj =e= sum(w, fixed*open(w)) + sum((w,s), supplyCost(s,w)*supply(s,w)); \n"
81 " \n"
82 "oneWarehouse(s).. sum(w, supply(s,w)) =e= 1; \n"
83 " \n"
84 "defopen(w).. sum(s, supply(s,w)) =l= open(w)*capacity(w); \n"
85 " \n"
86 "$ifthen %disaggregate%==1 \n"
87 "Equations \n"
88 " defopen2(s,w); \n"
89 "defopen2(s,w).. supply(s,w) =l= open(w); \n"
90 "$endif \n"
91 " \n"
92 "model distrib /all/; \n"
93 "solve distrib min obj using mip; \n"
94 " \n"
95 "$macro setResult(n) option clear=ares; ares(n) = yes; \n"
96 "if (distrib.modelstat=%ModelStat.LicensingProblem% or \n"
97 " distrib.solvestat=%Solvestat.LicensingProblems%, \n"
98 " setResult('1'); \n"
99 " abort 'License Error'; \n"
100 "); \n"
101 "if (distrib.solvestat<>%SolveStat.NormalCompletion% or \n"
102 " distrib.modelstat<>%ModelStat.Optimal% and \n"
103 " distrib.modelstat<>%ModelStat.IntegerSolution%, \n"
104 " setResult('2'); \n"
105 " abort 'No solution'; \n"
106 "); \n"
107 "setResult('0'); \n";
108}
109
110void solveWarehouse(GAMSWorkspace* ws, int numberOfWarehouses, GAMSDatabase* resultDB, mutex* dbMutex)
111{
113 try{
114 // instantiate GAMSOptions and define some scalars
115 GAMSOptions gmsOpt = ws->addOptions();
116 gmsOpt.setAllModelTypes("cplex");
117 gmsOpt.setDefine("Warehouse", to_string(numberOfWarehouses));
118 gmsOpt.setDefine("Store", "65");
119 gmsOpt.setDefine("fixed", "22");
120 gmsOpt.setDefine("disaggregate", "0");
121 gmsOpt.setOptCR(0.0);
122
123 // create a GAMSJob from string and write results to the result database
124 gmsJ.run(gmsOpt);
125
126 // need to lock database write operations
127 {
128 lock_guard<mutex> dbLock(*dbMutex);
129 resultDB->getParameter("objrep").addRecord(to_string(numberOfWarehouses)).setValue(gmsJ.outDB().getVariable("obj").findRecord().level());
130 }
131
132 for(GAMSVariableRecord supplyRec : gmsJ.outDB().getVariable("supply"))
133 {
134 if (supplyRec.level() > 0.5)
135 {
136 lock_guard<mutex> dbLock(*dbMutex);
137 resultDB->getSet("supplyMap").addRecord(to_string(numberOfWarehouses), supplyRec.key(0), supplyRec.key(1));
138 }
139 }
140 }
141 catch(GAMSExceptionExecution& e)
142 {
144 {
145 lock_guard<mutex> dbLock(*dbMutex);
146 statusString = gmsJ.outDB().getSet("res").findRecord(gmsJ.outDB().getSet("ares").firstRecord().key(0)).text();
147 }
148 {
149 lock_guard<mutex> dbLock(*dbMutex);
150 status = e.rc();
151 }
152 }
153 catch (GAMSException& e)
154 {
155 cout << e.what() << endl;
156 lock_guard<mutex> dbLock(*dbMutex);
157 status = -1;
158 }
159 catch (exception& e)
160 {
161 cout << e.what() << endl;
162 lock_guard<mutex> dbLock(*dbMutex);
163 status = -2;
164 }
165}
166
175int main(int argc, char* argv[])
176{
177 cout << "---------- Warehouse --------------" << endl;
178
179 try{
180 GAMSWorkspaceInfo wsInfo;
181 if (argc > 1)
182 wsInfo.setSystemDirectory(argv[1]);
183 GAMSWorkspace ws(wsInfo);
184
185 // create a GAMSDatabase for the results
186 GAMSDatabase resultDB = ws.addDatabase();
187
188 resultDB.addParameter("objrep", 1, "Objective value");
189 resultDB.addSet("supplyMap", 3, "Supply connection with level");
190 // run multiple parallel jobs
191 mutex dbMutex;
192 vector<thread> v;
193 for(int nrWarehouses=10; nrWarehouses<22; nrWarehouses++)
194 v.emplace_back([&ws, nrWarehouses, &resultDB, &dbMutex]{solveWarehouse(&ws, nrWarehouses, &resultDB, &dbMutex);});
195 for (auto& t : v)
196 t.join();
197 if (status > 0)
198 throw GAMSExceptionExecution("Error when running GAMS: " + GAMSEnum::text((GAMSEnum::GAMSExitCode) status) + " " + statusString, status, &ws);
199 else if (status == -1)
200 throw GAMSException("Error in GAMS API");
201 else if (status == -2)
202 throw exception();
203 // export the result database to a GDX file
204 resultDB.doExport("\\tmp\\resultCpp.gdx");
205 } catch (GAMSException &ex) {
206 cout << "GAMSException occured: " << ex.what() << endl;
207 } catch (exception &ex) {
208 cout << ex.what() << endl;
209 }
210 return status;
211}
GAMSSet addSet(const std::string &name, const int dimension, const std::string &explanatoryText="", GAMSEnum::SetType setType=GAMSEnum::SetType::Multi)
GAMSParameter addParameter(const std::string &name, const int dimension, const std::string &explanatoryText="")
void doExport(const std::string &filePath="")
GAMSSet getSet(const std::string &name)
GAMSParameter getParameter(const std::string &name)
GAMSVariable getVariable(const std::string &name)
static std::string text(GAMSEnum::SymbolType type)
GAMSDatabase outDB()
void setAllModelTypes(const std::string &solver)
void setOptCR(const double value)
void setDefine(const std::string &key, const std::string &value)
void setValue(const double val)
GAMSParameterRecord addRecord(const std::vector< std::string > &keys)
std::string text()
GAMSSetRecord findRecord(const std::vector< std::string > &keys)
GAMSSetRecord firstRecord(const std::vector< std::string > &slice)
GAMSSetRecord addRecord(const std::vector< std::string > &keys)
std::string key(int index)
GAMSVariableRecord findRecord(const std::vector< std::string > &keys)
void setSystemDirectory(std::string systemDir)
GAMSOptions addOptions()
GAMSJob addJobFromString(const std::string &gamsSource, const std::string &jobName="")
GAMSDatabase addDatabase(const std::string &databaseName="", const std::string &inModelName="")
string getModelText()
Get model as string.
Definition: warehouse.cpp:38