Skip to content

Commit

Permalink
Slight Refactoring of a few models
Browse files Browse the repository at this point in the history
  • Loading branch information
lecoutre committed Mar 14, 2024
1 parent 66c507f commit e81a99f
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 32 deletions.
50 changes: 35 additions & 15 deletions realistic/TTP_PV/TTP_PV.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@

def automaton():
qi, q01, q02, q03, q11, q12, q13 = states = "q", "q01", "q02", "q03", "q11", "q12", "q13"
tr2 = [(qi, 0, q01), (qi, 1, q11), (q01, 0, q02), (q01, 1, q11), (q11, 0, q01), (q11, 1, q12), (q02, 1, q11), (q12, 0, q01)]
tr3 = [(q02, 0, q03), (q12, 1, q13), (q03, 1, q11), (q13, 0, q01)]
return Automaton(start=qi, final={q for q in states if q != qi}, transitions=tr2 + tr3)
t2 = [(qi, 0, q01), (qi, 1, q11), (q01, 0, q02), (q01, 1, q11), (q11, 0, q01), (q11, 1, q12), (q02, 1, q11), (q12, 0, q01)]
t3 = [(q02, 0, q03), (q12, 1, q13), (q03, 1, q11), (q13, 0, q01)]
return Automaton(start=qi, final={q for q in states if q != qi}, transitions=t2 + t3)


A = automaton()
Expand Down Expand Up @@ -80,31 +80,51 @@ def automaton():
# computing travelled distances wrt venues of current and next-round games
[
[
(
If(h[i][0] == 1, Then=t[i][0] == 0),
If(h[i][0] != 1, Then=t[i][0] == distances[i][o[i][0]])

If(
h[i][0] == 1,
Then=t[i][0] == 0,
Else=t[i][0] == distances[i][o[i][0]]
) for i in range(nTeams)
],

[
(
If(h[i][k] == 1, h[i][k + 1] == 1, Then=t[i][k + 1] == 0),
If(h[i][k] != 1, h[i][k + 1] == 1, Then=t[i][k + 1] == distances[o[i][k]][i]),
If(h[i][k] == 1, h[i][k + 1] != 1, Then=t[i][k + 1] == distances[i][o[i][k + 1]]),
If(h[i][k] != 1, h[i][k + 1] != 1, Then=t[i][k + 1] == distances[o[i][k]][o[i][k + 1]])
Match(
(h[i][k], h[i][k + 1]),
Cases={
(1, 1): t[i][k + 1] == 0,
(0, 1): t[i][k + 1] == distances[o[i][k]][i],
(1, 0): t[i][k + 1] == distances[i][o[i][k + 1]],
(0, 0): t[i][k + 1] == distances[o[i][k]][o[i][k + 1]]
}
) for i in range(nTeams) for k in range(nRounds - 1)
],

[
(
If(h[i][-1] == 1, Then=t[i][-1] == 0),
If(h[i][-1] != 1, Then=t[i][-1] == distances[o[i][-1]][i])

If(
h[i][-1] == 1,
Then=t[i][-1] == 0,
Else=t[i][-1] == distances[o[i][-1]][i]
) for i in range(nTeams)
]
]
],

)

minimize(
# minimizing summed up travelled distance
Sum(t)
)

"""
1) Note how the Match structure is equivalent to:
(
If(h[i][k] == 1, h[i][k + 1] == 1, Then=t[i][k + 1] == 0),
If(h[i][k] != 1, h[i][k + 1] == 1, Then=t[i][k + 1] == distances[o[i][k]][i]),
If(h[i][k] == 1, h[i][k + 1] != 1, Then=t[i][k + 1] == distances[i][o[i][k + 1]]),
If(h[i][k] != 1, h[i][k + 1] != 1, Then=t[i][k + 1] == distances[o[i][k]][o[i][k + 1]])
) for i in range(nTeams) for k in range(nRounds - 1)
"""
7 changes: 6 additions & 1 deletion realistic/Tower/Tower.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ def min_transmit_power(t, h):
[tr[h] == MaximumArg([attenuation_i[h][t] * effective_power[pr[t]] for t in range(nTowers)], rank=rnk) for h in range(nHandsets)],

# ensuring minimum signal strength
[If(tr[h] == t, Then=pr[t] >= min_transmit_power(t, h)) for h in range(nHandsets) for t in range(nTowers)],
[
If(
tr[h] == t,
Then=pr[t] >= min_transmit_power(t, h)
) for h in range(nHandsets) for t in range(nTowers)
],

# determining which towers are overloaded
[od[t] == (Sum(demands[h] * (tr[h] == t) for h in range(nHandsets)) > capacities[t]) for t in range(nTowers)],
Expand Down
4 changes: 2 additions & 2 deletions realistic/UnitCommitment/UnitCommitment.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

gen_max, dispatch_cost, gen_min, init_commitment, startup_cost, shutdown_cost, max_ramp_rate, demand, shed_cost, min_down, max_num_start = data
horizon, nGenerators, nLoads = len(gen_max[0]), len(gen_max), len(demand)
maxg = max(v for row in gen_max for v in row)
maxg = max(max(row) for row in gen_max)

# x[i][t] is 1 if the ith generator is committed at time t
x = VarArray(size=[nGenerators, horizon], dom={0, 1})
Expand All @@ -32,7 +32,7 @@
gl = VarArray(size=[nGenerators, horizon], dom=range(maxg // 2 + 1))

# ll[j][t] is the loss of the jth load at time t
ll = VarArray(size=[nLoads, horizon], dom=lambda l, t: range(demand[l][t] + 1))
ll = VarArray(size=[nLoads, horizon], dom=lambda j, t: range(demand[j][t] + 1))

# up[i][t] is 1 if the ith generator is up at time t
up = VarArray(size=[nGenerators, horizon], dom={0, 1})
Expand Down
16 changes: 8 additions & 8 deletions realistic/VRP_LC/VRP_LC.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
from pycsp3 import *

horizon, nVehicles, vehicleCapacity, nLocations, locationCapacity, nPickups, times, requests = data
l, a, b, s, q = zip(*requests)
rl, ra, rb, rs, rq = zip(*requests)
nNodes, n = len(times), len(requests) # n is the number of requests (pickups and deliveries)

MainNodes = range(n + nVehicles) # request and start nodes
Depots = range(n, nNodes) # start and end nodes
qq = cp_array(list(q) + [0 for i in Depots])
load_changes = cp_array(list(rq) + [0 for _ in Depots])

# veh[i] is the vehicle visiting the ith node
veh = VarArray(size=nNodes, dom=range(nVehicles))
Expand Down Expand Up @@ -73,9 +73,9 @@
(
(
arr[i] <= ser[i],
ser[i] + s[i] <= dep[i],
a[i] <= ser[i],
ser[i] <= b[i]
ser[i] + rs[i] <= dep[i],
ra[i] <= ser[i],
ser[i] <= rb[i]
) for i in range(n)
),

Expand All @@ -89,7 +89,7 @@
[dep[i] + times[i][succ[i]] == arr[succ[i]] for i in MainNodes],

# accumulating load along route
[load[i] + qq[succ[i]] == load[succ[i]] for i in MainNodes],
[load[i] + load_changes[succ[i]] == load[succ[i]] for i in MainNodes],

# setting load at start and end nodes
[load[i] == 0 for i in Depots],
Expand All @@ -103,8 +103,8 @@
# handling service resources
[
Cumulative(
tasks=[Task(origin=ser[i], length=s[i], height=1) for i in range(n) if l[i] == ll]
) <= locationCapacity for ll in range(nLocations)
tasks=[Task(origin=ser[i], length=rs[i], height=1) for i in range(n) if rl[i] == p]
) <= locationCapacity for p in range(nLocations)
],

# tag(symmetry-breaking)
Expand Down
7 changes: 6 additions & 1 deletion realistic/Vaccine/Vaccine.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@
[Sum(x[i]) <= sizes[i] // min_size for i in range(nGroups)],

# imposing limits wrt vaccines and ages
[Cardinality([x[i][j] * ages[i] for i in range(nGroups)], occurrences={a + 1: bounds for a, bounds in enumerate(ageBounds)}) for j in range(nVaccines)],
[
Cardinality(
[x[i][j] * ages[i] for i in range(nGroups)],
occurrences={a + 1: bounds for a, bounds in enumerate(ageBounds)}
) for j in range(nVaccines)
],

# computing the total number of vaccinated persons
[y[v] == Sum(x[g][v] * (sizes[g] // (1 + Sum(x[g][j] for j in range(nVaccines) if j != v))) for g in range(nGroups)) for v in range(nVaccines)],
Expand Down
6 changes: 4 additions & 2 deletions realistic/WWTPP/WWTPP.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ def table_spanning(i, start, stop):

satisfy(
# not exceeding the Wastewater Treatment Plant
[Sum(c[:, j] + d[:, j]) <= plantCapacity for j in range(nPeriods)],
[Sum(c[:, j], d[:, j]) <= plantCapacity for j in range(nPeriods)],

# managing scheduled discharge flows at period 0
[Sum(b[i][0], c[i][0]) == sd[i][0] for i in range(nIndustries) if sd[i][0] != 0],

# managing scheduled discharge flows at all periods except 0
[[b[i][j], b[i][j - 1], d[i][j], c[i][j]] * [1, -1, 1, 1 if c[i][j] else None] == sd[i][j] for i in range(nIndustries) for j in range(1, nPeriods)],
[Sum(b[i][j], -b[i][j - 1], d[i][j], c[i][j]) == sd[i][j] for i in range(nIndustries) for j in range(1, nPeriods)],

# ensuring compatibility between stored and discharge flows
[(d[i][j], b[i][j - 1]) in table_compatibility(i, j) for i in range(nIndustries) for j in range(1, nPeriods)],
Expand All @@ -64,4 +64,6 @@ def table_spanning(i, start, stop):
""" Comments
1) when managing scheduled discharge flows, we have a list with four cells for variables and integers.
However, when there is the special value None (at the fourth position in both lists), the two lists will be automatically reduced to three cells.
2) one could also write the more complex expression:
[[b[i][j], b[i][j - 1], d[i][j], c[i][j]] * [1, -1, 1, 1 if c[i][j] else None] == sd[i][j] for i in range(nIndustries) for j in range(1, nPeriods)],
"""
1 change: 0 additions & 1 deletion realistic/Zephyrus/Zephyrus.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
The model, below, is close to (can be seen as the close translation of) the one submitted to the 2016/2019 challenges.
The MZN model was proposed by Jacopo Mauro (under the terms of the ISC License)
No Licence was explicitly mentioned (MIT Licence assumed).
## Data Example
12-06-8-3.json
Expand Down
5 changes: 4 additions & 1 deletion recreational/Dominoes/Dominoes.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@
# adjacency constraints
If(
d != nCols, # if not adjacent in the same column
Then=both(d == 1, x[i][j] // nCols == y[i][j] // nCols) # then adjacent in the same line
Then=both( # then adjacent in the same line
d == 1,
x[i][j] // nCols == y[i][j] // nCols
)
) for i, j in dominoes if (d := abs(x[i][j] - y[i][j]),)
)

Expand Down
2 changes: 1 addition & 1 deletion recreational/Fillomino/Fillomino_z.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

def join(r, c):
return [
AllHold( # TODO AllHold vs conjunction
AllHold( # TODO test AllHold vs conjunction
when[r][c] == 1 + when[rr][cc],
area[r][c] == area[rr][cc],
what[r][c] == what[rr][cc]
Expand Down

0 comments on commit e81a99f

Please sign in to comment.