Skip to content

Commit fb702d1

Browse files
committed
improved implementation using networkx
1 parent 63a07dd commit fb702d1

File tree

1 file changed

+32
-114
lines changed

1 file changed

+32
-114
lines changed

models/lop/lop.py

Lines changed: 32 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@
4848
from gamspy import Smax
4949
from gamspy import Sum
5050
from gamspy import Variable
51-
51+
import networkx as nx
5252

5353
def main():
5454
m = Container(
55+
system_directory=os.getenv("SYSTEM_DIRECTORY", None),
5556
load_from=str(Path(__file__).parent.absolute()) + "/lop.gdx",
5657
)
5758

@@ -61,6 +62,14 @@ def main():
6162
# Parameters
6263
rt, tt, lfr, od = m.getSymbols(["rt", "tt", "lfr", "od"])
6364

65+
66+
# create graph
67+
68+
G = nx.Graph()
69+
G.add_nodes_from(s.records['uni'])
70+
edges = list(zip(rt.records['s_0'], rt.records['s_1'], rt.records['value']))
71+
G.add_weighted_edges_from(edges)
72+
6473
# Scalars
6574
mincars, ccap, cfx, crm, trm, cmp, maxtcap = m.getSymbols(
6675
["mincars", "ccap", "cfx", "crm", "trm", "cmp", "maxtcap"]
@@ -72,136 +81,45 @@ def main():
7281
# Variables
7382
f, spobj = m.getSymbols(["f", "spobj"])
7483

75-
# Equations
76-
balance, defspobj = m.getSymbols(["balance", "defspobj"])
84+
predecessors, _ = nx.floyd_warshall_predecessor_and_distance(G)
85+
86+
lines = dict()
87+
for n1 in G.nodes():
88+
for n2 in G.nodes():
89+
if n1 != n2 and lines.get((n2, n1), None) is None:
90+
lines[(n1, n2)] = nx.reconstruct_path(n1, n2, predecessors)
91+
92+
l_rec = []
93+
rp_rec = []
94+
for l, path in lines.items():
95+
for i in range(len(path)):
96+
if i != len(path)-1:
97+
arc = (path[i], path[i + 1])
98+
l_rec.append(l + (arc))
99+
l_rec.append(l + (arc[::-1]))
100+
rp_rec.append(l + (path[i], i + 1))
101+
77102

78-
balance[s, s1] = (
79-
Sum(d[s1, s2], f[s, d])
80-
== Sum(d[s2, s1], f[s, d]) + s.sameAs(s1) * Card(s) - 1
81-
)
82-
83-
defspobj[...] = spobj == Sum(
84-
(s, d[s1, s2]), f[s, d] * gams_math.Max(rt[s1, s2], rt[s2, s1])
85-
)
86-
87-
sp = Model(
88-
m,
89-
"sp",
90-
equations=[balance, defspobj],
91-
problem="LP",
92-
sense=Sense.MIN,
93-
objective=spobj,
94-
)
95-
sp.solve()
96-
97-
tree = Set(
98-
m, "tree", domain=[s, s1, s2], description="shortest path tree from s"
99-
)
100-
tree[s, s1, s2] = f.l[s, s1, s2]
101-
102-
r = Set(
103-
m, "r", records=[str(idx) for idx in range(1, 101)], description="rank"
104-
)
105-
k = Set(m, "k", domain=[s, s], description="arcs from root to a node")
106-
v = Set(
107-
m,
108-
"v",
109-
domain=[s, r],
110-
description="nodes with rank from root to a node",
111-
)
112-
unvisit = Set(m, "unvisit", domain=s, description="unvisited nodes")
113-
visit = Set(m, "visit", domain=s, description="visited nodes")
114-
from_ = Set(m, "from", domain=s, description="from nodes")
115-
to = Set(m, "to", domain=s, description="to nodes")
116103
l = Set(
117104
m,
118105
"l",
119106
domain=[s, s1, s2, s3],
120107
description="line from s to s1 with edge s2s3",
108+
records=l_rec
121109
) # noqa: E741
122-
lr = Set(
123-
m,
124-
"lr",
125-
domain=[s, s1, s2, r],
126-
description="rank of s2 in line from s to s1",
127-
)
128-
129110
root = Alias(m, "root", s)
130-
r1 = Alias(m, "r1", r)
131-
132-
l[root, s, s1, s2] = False
133-
lr[root, s, s1, r] = False
134-
135-
counter = 0
136-
137-
for root_elem in root.toList():
138-
from_[root_elem] = True
139-
unvisit[s] = True
140-
visit[s] = False
141-
142-
for r_elem in r.toList():
143-
if int(r_elem) > 1 and len(unvisit):
144-
unvisit[from_] = False
145-
visit[from_] = True
146-
to[unvisit] = Sum(tree[root_elem, from_, unvisit], True)
147-
148-
for f_elem in from_.toList():
149-
k[s2, s3].where[l[root_elem, f_elem, s2, s3]] = True
150-
v[s2, r1].where[lr[root_elem, f_elem, s2, r1]] = True
151-
v[f_elem, "1"].where[Card(k) == 0] = True
152-
153-
l[root_elem, to, k].where[tree[root_elem, f_elem, to]] = (
154-
True
155-
)
156-
lr[root_elem, to, v].where[tree[root_elem, f_elem, to]] = (
157-
True
158-
)
159-
l[root_elem, to, f_elem, to].where[
160-
tree[root_elem, f_elem, to]
161-
] = True
162-
lr[root_elem, to, to, r_elem].where[
163-
tree[root_elem, f_elem, to]
164-
] = True
165-
166-
k[s2, s3] = False
167-
v[s2, r1] = False
168-
169-
from_[s] = False
170-
from_[to] = True
171-
to[s] = False
172-
173-
counter += 1
174-
175-
from_[s] = False
176-
177-
error02 = Set(
178-
m,
179-
"error02",
180-
domain=[s1, s2],
181-
description="arcs not covered by shortest path lines",
182-
)
183-
error02[s1, s2] = lfr[s1, s2] & (Sum(l[root, s, s1, s2], 1) == 0)
184-
185-
if len(error02):
186-
sys.exit(f"There is an error {error02.records}")
187111

188112
ll = Set(
189113
m, "ll", domain=[s, s], description="station pair represening a line"
190114
)
191115
ll[s1, s2] = Ord(s1) < Ord(s2)
192116

193-
l[root, s, s1, s2].where[~ll[root, s]] = False
194-
lr[root, s, s1, r].where[~ll[root, s]] = False
195-
196-
l[root, s, s1, s2].where[l[root, s, s2, s1] & rt[s1, s2]] = True
197117
l[root, s, s1, s2].where[~rt[s1, s2]] = False
198118

199-
rp = Parameter(m, "rp", domain=[s, s, s], description="rank of node")
119+
rp = Parameter(m, "rp", domain=[s, s, s], description="rank of node", records=rp_rec)
200120
lastrp = Parameter(
201121
m, "lastrp", domain=[s, s], description="rank of the last node in line"
202122
)
203-
204-
rp[ll, s] = Sum(r.where[lr[ll, s, r]], Ord(r))
205123
lastrp[ll] = Smax(s, rp[ll, s])
206124

207125
load = Parameter(
@@ -293,7 +211,7 @@ def main():
293211
length[ll] = Sum(l[ll, s1, s2], rt[s1, s2])
294212
sigma[ll] = (
295213
length[ll]
296-
+ Sum(s.where[lr[ll, s, "1"]], tt[s])
214+
+ Sum(s.where[rp[ll, s] == 1], tt[s])
297215
+ Sum(s.where[rp[ll, s] == lastrp[ll]], tt[s])
298216
) / 60
299217

@@ -465,4 +383,4 @@ def main():
465383

466384

467385
if __name__ == "__main__":
468-
main()
386+
main()

0 commit comments

Comments
 (0)