Loading...
Searching...
No Matches
TransportEngine.java
1package com.gams.examples.transport;
2
3import java.io.*;
4import java.nio.file.*;
5import java.util.*;
6import java.nio.charset.*;
7
8import com.gams.api.*;
9
19public class TransportEngine {
20
21 public static void main(String[] args) {
23 // check workspace info from command line arguments
24 if (args.length > 0)
25 wsInfo.setSystemDirectory( args[0] );
26 // create and working directory named "TransportEngine" under current working directory
27 File workingDirectory = new File(System.getProperty("user.dir"), "TransportEngine");
28 workingDirectory.mkdir();
29 wsInfo.setWorkingDirectory(workingDirectory.getAbsolutePath());
30 // create GAMSWorkspace "ws" with user-specified system directory
31 GAMSWorkspace ws = new GAMSWorkspace(wsInfo);
32
33 String engine_url = System.getenv("ENGINE_URL");
34 if (engine_url == null) {
35 System.out.println("Error: environment variable ENGINE_URL not set");
36 System.exit(-1);
37 }
38 String engine_user = System.getenv("ENGINE_USER");
39 if (engine_user == null) {
40 System.out.println("Error: environment variable ENGINE_USER not set");
41 System.exit(-1);
42 }
43 String engine_password = System.getenv("ENGINE_PASSWORD");
44 if (engine_password == null) {
45 System.out.println("Error: environment variable ENGINE_PASSWORD not set");
46 System.exit(-1);
47 }
48 String engine_namespace = System.getenv("ENGINE_NAMESPACE");
49 if (engine_namespace == null) {
50 System.out.println("Error: environment variable ENGINE_NAMESPACE not set");
51 System.exit(-1);
52 }
53
54 // set up configuration required for any job on GAMS Engine
55 GAMSEngineConfiguration engine_configuration = new GAMSEngineConfiguration(
56 engine_url,
57 engine_user,
58 engine_password,
59 "",
60 engine_namespace
61 );
62 // run Engine Job
63 runEngineJob(ws, engine_configuration);
64
65 // run and interrupt Engine Job
66 runAndInterruptEngineJob(ws, engine_configuration);
67
68 // terminate
69 System.exit(0);
70 }
71
72 /* Example how to run Engine job */
73 static void runEngineJob(GAMSWorkspace ws, GAMSEngineConfiguration engine_configuration) {
74 /* Run with data from a string with GAMS syntax with explicit export to GDX file */
75 GAMSJob tEdata = ws.addJobFromString(data);
76 try {
77 System.out.println("Running data from string");
79 .setRunEngineConfiguration(engine_configuration)
80 .setOutput( System.out )
81 .build()
82 );
83 } catch (GAMSException e) {
84 System.out.println("Error: " + e.getMessage());
85 System.exit(-1);
86 }
87 GAMSDatabase tEDataDB = tEdata.OutDB();
88 tEDataDB.export("tdata.gdx");
89
90 Map<String, Double> expectedLevels = new HashMap<String, Double>();
91 {
92 expectedLevels.put( "seattle.new-york", Double.valueOf(0.0));
93 expectedLevels.put( "seattle.chicago", Double.valueOf(300.0));
94 expectedLevels.put( "seattle.topeka", Double.valueOf(0.0));
95 expectedLevels.put( "san-diego.new-york", Double.valueOf(325.0));
96 expectedLevels.put( "san-diego.chicago", Double.valueOf(0.0));
97 expectedLevels.put( "san-diego.topeka", Double.valueOf(275.0));
98 }
99
100 /* Run a job using an instance of GAMSOptions that defines the data include file */
101 GAMSJob tEmodel = ws.addJobFromString(model);
102 GAMSOptions opt = ws.addOptions();
103 opt.defines("gdxincname", "tdata");
104 opt.setAllModelTypes("xpress");
105 try {
106 System.out.println("Running using an instance of GAMSOptions that defines the data include file.");
108 .setRunEngineConfiguration( engine_configuration )
109 .setGAMSOptions( opt )
110 .setExtraModelFiles( new HashSet<String>(Arrays.asList("tdata.gdx")) )
111 .setEngineOptions( new HashMap<String, String>() {
112 { put( "inex_string", "{\"type\": \"include\", \"files\": [\"*.gdx\"]}" ); }
113 })
114 .build()
115 );
116
117 System.out.println("Ran model using an instance of GAMSOptions that defines the data include file:");
118 for (GAMSVariableRecord rec : tEmodel.OutDB().getVariable("x")) {
119 System.out.print("x(" + rec.getKey(0) + ", " + rec.getKey(1) + "):");
120 System.out.print(", level = " + rec.getLevel());
121 System.out.println(", marginal = " + rec.getMarginal());
122 double diff = expectedLevels.get(rec.getKey(0)+"."+rec.getKey(1)).doubleValue() - rec.getLevel();
123 if (Math.abs(diff) > 0.01) {
124 System.out.println("Unexpected result, expected level: "+expectedLevels.get(rec.getKey(0)+"."+rec.getKey(1)));
125 System.exit(-1);
126 }
127 }
128 } catch (GAMSException e) {
129 System.out.println("Error: " + e.getMessage());
130 System.exit(-1);
131 }
132
133 /* Same but with implicit database communication */
134 GAMSJob tEa = ws.addJobFromString(data);
135 try {
136 System.out.println("Running data from a string.");
138 .setRunEngineConfiguration(engine_configuration)
139 .setOutput( System.out )
140 .build()
141 );
142 } catch (GAMSException e) {
143 System.out.println("Error: " + e.getMessage());
144 System.exit(-1);
145 }
146
147 GAMSJob tEb = ws.addJobFromString(model);
148
150 GAMSOptions option = ws.addOptions();
151 option.defines("gdxincname", tEa.OutDB().getName());
152 option.setAllModelTypes("xpress");
153
154 try {
155 System.out.println("Running model from a string with checkpoint implicit database communication.");
157 .setRunEngineConfiguration( engine_configuration )
158 .setGAMSOptions( option )
159 .setGAMSCheckpoint( cp )
160 .setDatabases( new ArrayList<GAMSDatabase>(Arrays.asList(tEa.OutDB())) )
161 .setOutput( System.out )
162 .build()
163 );
164 System.out.println("Ran model from a string with checkpoint implicit database communication:");
165 for (GAMSVariableRecord rec : tEb.OutDB().getVariable("x")) {
166 System.out.print("x(" + rec.getKey(0) + ", " + rec.getKey(1) + "):");
167 System.out.print(", level = " + rec.getLevel());
168 System.out.println(", marginal = " + rec.getMarginal());
169 double diff = expectedLevels.get(rec.getKey(0)+"."+rec.getKey(1)).doubleValue() - rec.getLevel();
170 if (Math.abs(diff) > 0.01) {
171 System.out.println("Unexpected result, expected level: "+expectedLevels.get(rec.getKey(0)+"."+rec.getKey(1)));
172 System.exit(-1);
173 }
174 }
175 } catch (GAMSException e) {
176 System.out.println("Error: " + e.getMessage());
177 System.exit(-1);
178 }
179
180 List<HashMap<String, Double>> bmultExpected = new ArrayList<HashMap<String, Double>>();
181 bmultExpected.add( new HashMap<String, Double>() {
182 { put( "bmult", Double.valueOf(0.9) );
183 put( "ms", Double.valueOf(1) );
184 put( "ss", Double.valueOf(1) );
185 put( "obj", Double.valueOf(138.31) );
186 }
187 } );
188 bmultExpected.add( new HashMap<String, Double>() {
189 { put( "bmult", Double.valueOf(1.2) );
190 put( "ms", Double.valueOf(4) );
191 put( "ss", Double.valueOf(1) );
192 put( "obj", Double.valueOf(184.41) );
193 }
194 } );
195
196 for (HashMap<String, Double> m : bmultExpected) {
197 String bmultmodel = "bmult="+m.get("bmult")+"; solve transport min z use lp; ms=transport.modelstat; ss=transport.solvestat;";
198 GAMSJob tEbmult = ws.addJobFromString( bmultmodel, cp );
199 try {
200 System.out.println("Running model from a string with bmult="+m.get("bmult"));
202 .setRunEngineConfiguration(engine_configuration)
203 .setOutput( System.out )
204 .build()
205 );
206
207 System.out.println("Ran model from a string with bumult=" + m.get("bmult").doubleValue() + ":");
208 System.out.println(" Modelstatus: " + tEbmult.OutDB().getParameter("ms").getFirstRecord().getValue());
209 System.out.println(" Solvestatus: " + tEbmult.OutDB().getParameter("ss").getFirstRecord().getValue());
210 System.out.println(" Obj: " + tEbmult.OutDB().getVariable("z").getFirstRecord().getLevel());
211 double diff = tEbmult.OutDB().getParameter("bmult").getFirstRecord().getValue() - m.get("bmult").doubleValue();
212 if (Math.abs(diff) > 0.01) {
213 System.out.println("Unexpected result, expected bmult: "+m.get("bmult").doubleValue());
214 System.exit(-1);
215 }
216 diff = tEbmult.OutDB().getParameter("ms").getFirstRecord().getValue() - m.get("ms").doubleValue();
217 if (Math.abs(diff) > 0.01) {
218 System.out.println("Unexpected result, expected ms: "+m.get("ms").doubleValue());
219 System.exit(-1);
220 }
221 diff = tEbmult.OutDB().getParameter("ss").getFirstRecord().getValue() - m.get("ss").doubleValue();
222 if (Math.abs(diff) > 0.01) {
223 System.out.println("Unexpected result, expected ss: "+m.get("ss").doubleValue());
224 System.exit(-1);
225 }
226 diff = tEbmult.OutDB().getVariable("z").getFirstRecord().getLevel() - m.get("obj").doubleValue();
227 if (Math.abs(diff) > 0.01) {
228 System.out.println("Unexpected result, expected obj: "+m.get("obj").doubleValue());
229 System.exit(-1);
230 }
231
232 } catch (GAMSException e) {
233 System.out.println("Error: " + e.getMessage());
234 System.exit(-1);
235 }
236
237 }
238
239 // dispose option and database
240 opt.dispose();
241 option.dispose();
242
243 tEDataDB.dispose();
244 }
245
247 static void runAndInterruptEngineJob(GAMSWorkspace ws, GAMSEngineConfiguration engine_configuration) {
248 final GAMSJob job = ws.addJobFromGamsLib("clad");
249 final GAMSOptions opt = ws.addOptions();
250 opt.setMIP("cplex");
251 opt.setOptFile(1);
252 opt.setSolveLink(GAMSOptions.ESolveLink.LoadLibrary);
253
254 try {
255 File logFile = Paths.get(ws.workingDirectory(), "jclad.log").toFile();
256 boolean fileCreated = logFile.createNewFile();
257
258 File optionFile_1 = Paths.get(ws.workingDirectory(), "cplex.opt").toFile();
259 FileWriter fw = new FileWriter(optionFile_1);
260 fw.write("epgap 0\n"); // set relative stopping tolerance to 0 initially
261 fw.write("interactive 1\n"); // activate interactive option setting on interrupt
262 fw.write("iafile cplex.op2\n"); // define new option file to read on interrupt
263 fw.close();
264
265 File optionFile_2 = Paths.get(ws.workingDirectory(), "cplex.op2").toFile();
266 fw = new FileWriter(optionFile_2);
267 fw.write("epgap 0.1\n"); // set relative stopping tolerance to 0.1
268 fw.close();
269
270 HashSet<String> extraModelFiles = new HashSet<String>(
271 Arrays.asList(optionFile_1.getAbsolutePath(), optionFile_2.getAbsolutePath(), "claddat.gdx")
272 );
273 final Worker w = new Worker(job, engine_configuration, opt, extraModelFiles, new PrintStream(logFile));
274 w.start();
275
276 while (true) {
277 if (logFile.exists() && logFile.length()==0) {
278 try {
279 Thread.currentThread();
280 Thread.sleep(500);
281 } catch ( Exception e ) {
282 e.printStackTrace();
283 }
284 continue;
285 }
286
287 // Send interrupt signal to running GAMSJob only when job is not yet terminated
288 boolean interrupted = false;
289 boolean terminated = (w.getState()==Thread.State.TERMINATED);
290 if (!terminated) {
291 System.out.println("Sending interrupt GAMS job...");
292 interrupted = job.interrupt();
293 }
294 System.out.println("Interrupted Cplex to continue with new option.");
295 break;
296 }
297
298 if (w.isAlive()) {
299 try {
300 w.join();
301 } catch (InterruptedException e) { e.printStackTrace(); }
302 }
303
304 boolean interrupted = false;
305
306 Scanner scan = new Scanner(logFile);
307 String searchstr = "interrupted...";
308 while (scan.hasNext()) {
309 String line = scan.nextLine().toLowerCase().toString();
310 if (line.contains(searchstr)) {
311 System.out.println(line);
312 interrupted = true;
313 break;
314 }
315 }
316
317 if (!interrupted) {
318 System.out.println("Expected the solver to be interrupted at least once.");
319 System.exit(-1);
320 }
321 System.out.println("Interrupted successfully");
322
323 } catch (FileNotFoundException e) {
324 e.printStackTrace();
325 } catch (IOException e) {
326 e.printStackTrace();
327 }
328 opt.dispose();
329 }
330
332 static class Worker extends Thread {
333 GAMSEngineConfiguration configuration;
334 GAMSJob job;
335 GAMSOptions option;
336 PrintStream output;
337 HashSet<String> extraModelFiles;
338
346 public Worker(GAMSJob jb, GAMSEngineConfiguration cfg, GAMSOptions opt, HashSet<String> modelFiles, PrintStream out) {
347 configuration = cfg;
348 job = jb;
349 option = opt;
350 output = out;
351 extraModelFiles = modelFiles;
352 }
353
355 @Override
356 public void run() {
357 try {
358 System.out.println("Running GAMS Engine job...");
360 .setRunEngineConfiguration(configuration)
361 .setGAMSOptions(option)
362 .setOutput(output)
363 .setExtraModelFiles( extraModelFiles )
364 .build()
365 );
366 } catch(Exception e) {
367 e.printStackTrace();
368 System.exit(-1);
369 }
370 }
371 }
372
373 // data
374 static String data =
375 "Sets \n" +
376 " i canning plants / seattle, san-diego / \n" +
377 " j markets / new-york, chicago, topeka / ; \n" +
378 "Parameters \n" +
379 " \n" +
380 " a(i) capacity of plant i in cases \n" +
381 " / seattle 350 \n" +
382 " san-diego 600 / \n" +
383 " \n" +
384 " b(j) demand at market j in cases \n" +
385 " / new-york 325 \n" +
386 " chicago 300 \n" +
387 " topeka 275 / ; \n" +
388 " \n" +
389 "Table d(i,j) distance in thousands of miles \n" +
390 " new-york chicago topeka \n" +
391 " seattle 2.5 1.7 1.8 \n" +
392 " san-diego 2.5 1.8 1.4 ; \n" +
393 " \n" +
394 "Scalar f 'freight in dollars per case per thousand miles' / 90 / \n" +
395 " bmult 'demand multiplier' / 1 /;\n" +
396 " \n" ;
397
398 // model
399 static String model =
400 " Sets \n"+
401 " i 'canning plants' \n"+
402 " j 'markets'; \n"+
403 " \n"+
404 "Parameters \n"+
405 " a(i) 'capacity of plant i in cases' \n"+
406 " b(j) 'demand at market j in cases' \n"+
407 " d(i,j) 'distance in thousands of miles'; \n"+
408 " \n"+
409 "Scalar f 'freight in dollars per case per thousand miles'; \n"+
410 "Scalar bmult 'demand multiplier'; \n"+
411 " \n"+
412 "$if not set gdxincname $abort 'no include file name for data file provided'\n"+
413 "$gdxin %gdxincname% \n"+
414 "$load i j a b d f bmult \n"+
415 "$gdxin \n"+
416 " \n"+
417 "$echo test > test.txt \n"+
418 " \n"+
419 "Parameter c(i,j) 'transport cost in thousands of dollars per case'; \n"+
420 " c(i,j) = f * d(i,j) / 1000 ; \n"+
421 " \n"+
422 "Variables \n"+
423 " x(i,j) shipment quantities in cases \n"+
424 " z total transportation costs in thousands of dollars ; \n"+
425 " \n"+
426 "Positive Variable x; \n"+
427 " \n"+
428 "Equations \n"+
429 " cost 'define objective function' \n"+
430 " supply(i) 'observe supply limit at plant i' \n"+
431 " demand(j) 'satisfy demand at market j'; \n"+
432 " \n"+
433 "cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ; \n"+
434 " \n"+
435 "supply(i) .. sum(j, x(i,j)) =l= a(i) ; \n"+
436 " \n"+
437 "demand(j) .. sum(i, x(i,j)) =g= bmult*b(j) ; \n"+
438 " \n"+
439 "Model transport /all/ ; \n"+
440 " \n"+
441 "solve transport using lp minimizing z; \n"+
442 " \n"+
443 "Scalar \n"+
444 " ms 'model status' \n"+
445 " ss 'solve status'; \n"+
446 " \n"+
447 "Display x.l, x.m ; \n";
448}
GAMSParameter getParameter(String identifier)
GAMSVariable getVariable(String identifier)
newBuilder setEngineOptions(HashMap< String, String > options)
newBuilder setExtraModelFiles(Set< String > modelFiles)
void runEngine(GAMSEngineRunParameters parameters)
GAMSDatabase OutDB()
void defines(String defStr, String asStr)
void setAllModelTypes(String value)
void setSolveLink(GAMSOptions.ESolveLink x)
void setSystemDirectory(String directory)
void setWorkingDirectory(String directory)
GAMSJob addJobFromString(String source)
GAMSCheckpoint addCheckpoint()
GAMSJob addJobFromGamsLib(String modelName)
This example shows how to run a GAMSJob on GAMS Engine using the runEngine method (since GAMS 44):
Provides package namespace for Java interface and examples to General Algebraic Model System (GAMS).
&#160;