Loading...
Searching...
No Matches
transport8.py
Go to the documentation of this file.
9
10import sys
11from threading import Lock, Thread
12from gams import GamsWorkspace, GamsModifier
13
14GAMS_MODEL = """
15Set
16 i 'canning plants' / seattle, san-diego /
17 j 'markets' / new-york, chicago, topeka /;
18
19Parameter
20 a(i) 'capacity of plant i in cases'
21 / seattle 350
22 san-diego 600 /
23
24 b(j) 'demand at market j in cases'
25 / new-york 325
26 chicago 300
27 topeka 275 /;
28
29Table d(i,j) 'distance in thousands of miles'
30 new-york chicago topeka
31 seattle 2.5 1.7 1.8
32 san-diego 2.5 1.8 1.4;
33
34Scalar
35 f 'freight in dollars per case per thousand miles' / 90 /
36 bmult 'demand multiplier' / 1 /;
37
38Parameter c(i,j) 'transport cost in thousands of dollars per case';
39c(i,j) = f*d(i,j)/1000;
40
41Variable
42 x(i,j) 'shipment quantities in cases'
43 z 'total transportation costs in thousands of dollars';
44
45Positive Variable x;
46
47Equations
48 cost 'define objective function'
49 supply(i) 'observe supply limit at plant i'
50 demand(j) 'satisfy demand at market j';
51
52cost.. z =e= sum((i,j), c(i,j)*x(i,j));
53
54supply(i).. sum(j, x(i,j)) =l= a(i);
55
56demand(j).. sum(i, x(i,j)) =g= bmult*b(j);
57
58Model transport /all/;
59"""
60
61
62def scen_solve(checkpoint, bmult_list, list_lock, io_lock):
63 list_lock.acquire()
64 mi = checkpoint.add_modelinstance()
65 list_lock.release()
66 bmult = mi.sync_db.add_parameter("bmult", 0, "demand multiplier")
67 opt = ws.add_options()
68 opt.all_model_types = "cplex"
69
70 # instantiate the GamsModelInstance and pass a model definition and GamsModifier to declare bmult mutable
71 mi.instantiate("transport use lp min z", GamsModifier(bmult), opt)
72 bmult.add_record().value = 1.0
73
74 while True:
75 # dynamically get a bmult value from the queue instead of passing it to the different threads at creation time
76 list_lock.acquire()
77 if not bmult_list:
78 list_lock.release()
79 return
80 b = bmult_list.pop()
81 list_lock.release()
82 bmult.first_record().value = b
83 mi.solve()
84
85 # we need to make the ouput a critical section to avoid messed up report informations
86 io_lock.acquire()
87 print(f"Scenario bmult={b}:")
88 print(f" Modelstatus: {mi.model_status}")
89 print(f" Solvestatus: {mi.solver_status}")
90 print(f" Obj: {mi.sync_db['z'].first_record().level}")
91 io_lock.release()
92
93
94if __name__ == "__main__":
95 sys_dir = sys.argv[1] if len(sys.argv) > 1 else None
96 ws = GamsWorkspace(system_directory=sys_dir)
97
98 cp = ws.add_checkpoint()
99
100 # initialize a GamsCheckpoint by running a GamsJob
101 job = ws.add_job_from_string(GAMS_MODEL)
102 job.run(checkpoint=cp)
103
104 bmult_list = [1.3, 1.2, 1.1, 1.0, 0.9, 0.8, 0.7, 0.6]
105
106 # solve multiple model instances in parallel
107 list_lock = Lock()
108 io_lock = Lock()
109
110 # start 2 threads
111 nr_workers = 2
112 threads = {}
113 for i in range(nr_workers):
114 threads[i] = Thread(
115 target=scen_solve, args=(cp, bmult_list, list_lock, io_lock)
116 )
117 threads[i].start()
118 for i in range(nr_workers):
119 threads[i].join()