before LLM fucks things up
This commit is contained in:
commit
87b6529671
5 changed files with 775 additions and 0 deletions
1
.python-version
Normal file
1
.python-version
Normal file
|
|
@ -0,0 +1 @@
|
|||
3.13
|
||||
0
README.md
Normal file
0
README.md
Normal file
548
main.py
Normal file
548
main.py
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
"""
|
||||
City Resource Optimization -> CP-SAT (Google OR-Tools)
|
||||
|
||||
Maximise Electrum * Brass * Steel after the gains of step 5.
|
||||
|
||||
The objective is a product of three variables, so this is a constraint-
|
||||
programming / nonlinear problem, hence CP-SAT (cp_model) rather than the
|
||||
LP/MIP solver. Read the comments at:
|
||||
- PARAMETERS (initial pools + arrival schedule + bonus mode)
|
||||
- "OBJECTIVE IS SET HERE" (the product being maximised -- tweak freely)
|
||||
"""
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
|
||||
# ======================================================================
|
||||
# PARAMETERS -- edit these
|
||||
# ======================================================================
|
||||
|
||||
# Starting resource pools at the start of step 1: (Electrum, Brass, Steel, Capital)
|
||||
INITIAL = (3, 3, 3, 3)
|
||||
|
||||
# Arrival schedule. Key = step (1..5), value = list of city types that arrive
|
||||
# at the START of that step. Types: 'H' Hub, 'F' Foundry, 'M' Metropolis, 'N' Monument.
|
||||
# Total cities across all steps must be <= 7. Arriving cities act that same step.
|
||||
ARRIVALS = {
|
||||
1: ["H", "F", "H", "N", "F"],
|
||||
2: ["M"],
|
||||
3: [],
|
||||
4: [],
|
||||
5: [],
|
||||
}
|
||||
|
||||
# Collect Bonus (b) adds +1 to whatever a Collect gives. On a foundry that is
|
||||
# +1 of the resource collected (i.e. the chosen vat's value + 1). This is the
|
||||
# same uniform rule as Hub (+1 Capital) and Metropolis (+1 resource pick).
|
||||
|
||||
NUM_STEPS = 5
|
||||
MAX_RES = (
|
||||
200 # upper bound on any resource pool (raise if you expect more; affects speed)
|
||||
)
|
||||
MAX_VAT = 15 # upper bound on a foundry vat value (1 + 2*nsteps is plenty)
|
||||
|
||||
|
||||
# ======================================================================
|
||||
# MODEL
|
||||
# ======================================================================
|
||||
|
||||
|
||||
def solve(
|
||||
initial=INITIAL,
|
||||
arrivals=ARRIVALS,
|
||||
max_res=MAX_RES,
|
||||
max_vat=MAX_VAT,
|
||||
time_limit=60.0,
|
||||
num_workers=8,
|
||||
verbose=True,
|
||||
):
|
||||
|
||||
# ---- build the city list -----------------------------------------
|
||||
cities = [] # list of (arrival_step, arrival_type)
|
||||
for s in range(1, NUM_STEPS + 1):
|
||||
for typ in arrivals.get(s, []):
|
||||
cities.append((s, typ))
|
||||
N = len(cities)
|
||||
assert N <= 7, f"At most 7 cities allowed, got {N}"
|
||||
|
||||
m = cp_model.CpModel()
|
||||
|
||||
def AND(a, b):
|
||||
"""Boolean AND of two 0/1 vars, returned as a new 0/1 var."""
|
||||
c = m.NewBoolVar("")
|
||||
m.AddMultiplicationEquality(c, [a, b])
|
||||
return c
|
||||
|
||||
# ---- state variables ---------------------------------------------
|
||||
# Indexed [i][t]; t in 1..NUM_STEPS+1 for state (t=NUM_STEPS+1 == "after step 5").
|
||||
isH, isF, isM, isMon, present = {}, {}, {}, {}, {}
|
||||
hasA, hasB, hasD = {}, {}, {}
|
||||
vE, vB, vS = {}, {}, {} # foundry vats at start of step t
|
||||
|
||||
# action variables, t in 1..NUM_STEPS
|
||||
col, ua, ub, ud = {}, {}, {}, {} # collect / upgrade a,b,d
|
||||
rH, rF, rM = {}, {}, {} # renovate -> Hub/Foundry/Metro
|
||||
cvE, cvB, cvS = {}, {}, {} # foundry: which vat collected
|
||||
mE, mB, mS, mC = {}, {}, {}, {} # metropolis: resources picked (+1 each)
|
||||
|
||||
for i in range(N):
|
||||
a_step, a_type = cities[i]
|
||||
for t in range(1, NUM_STEPS + 2):
|
||||
isH[i, t] = m.NewBoolVar(f"isH_{i}_{t}")
|
||||
isF[i, t] = m.NewBoolVar(f"isF_{i}_{t}")
|
||||
isM[i, t] = m.NewBoolVar(f"isM_{i}_{t}")
|
||||
isMon[i, t] = m.NewBoolVar(f"isMon_{i}_{t}")
|
||||
present[i, t] = m.NewBoolVar(f"present_{i}_{t}")
|
||||
hasA[i, t] = m.NewBoolVar(f"hasA_{i}_{t}")
|
||||
hasB[i, t] = m.NewBoolVar(f"hasB_{i}_{t}")
|
||||
hasD[i, t] = m.NewBoolVar(f"hasD_{i}_{t}")
|
||||
vE[i, t] = m.NewIntVar(0, max_vat, f"vE_{i}_{t}")
|
||||
vB[i, t] = m.NewIntVar(0, max_vat, f"vB_{i}_{t}")
|
||||
vS[i, t] = m.NewIntVar(0, max_vat, f"vS_{i}_{t}")
|
||||
|
||||
# presence: present from arrival step onward, persists
|
||||
m.Add(present[i, t] == (1 if t >= a_step else 0))
|
||||
# exactly one type iff present
|
||||
m.Add(isH[i, t] + isF[i, t] + isM[i, t] + isMon[i, t] == present[i, t])
|
||||
|
||||
for t in range(1, NUM_STEPS + 1):
|
||||
col[i, t] = m.NewBoolVar(f"col_{i}_{t}")
|
||||
ua[i, t] = m.NewBoolVar(f"ua_{i}_{t}")
|
||||
ub[i, t] = m.NewBoolVar(f"ub_{i}_{t}")
|
||||
ud[i, t] = m.NewBoolVar(f"ud_{i}_{t}")
|
||||
rH[i, t] = m.NewBoolVar(f"rH_{i}_{t}")
|
||||
rF[i, t] = m.NewBoolVar(f"rF_{i}_{t}")
|
||||
rM[i, t] = m.NewBoolVar(f"rM_{i}_{t}")
|
||||
cvE[i, t] = m.NewBoolVar(f"cvE_{i}_{t}")
|
||||
cvB[i, t] = m.NewBoolVar(f"cvB_{i}_{t}")
|
||||
cvS[i, t] = m.NewBoolVar(f"cvS_{i}_{t}")
|
||||
mE[i, t] = m.NewIntVar(0, 3, f"mE_{i}_{t}")
|
||||
mB[i, t] = m.NewIntVar(0, 3, f"mB_{i}_{t}")
|
||||
mS[i, t] = m.NewIntVar(0, 3, f"mS_{i}_{t}")
|
||||
mC[i, t] = m.NewIntVar(0, 3, f"mC_{i}_{t}")
|
||||
|
||||
# ---- per-step gain/cost accumulators (linear expressions) ---------
|
||||
gain_E = {t: [] for t in range(1, NUM_STEPS + 1)}
|
||||
gain_B = {t: [] for t in range(1, NUM_STEPS + 1)}
|
||||
gain_S = {t: [] for t in range(1, NUM_STEPS + 1)}
|
||||
gain_C = {t: [] for t in range(1, NUM_STEPS + 1)}
|
||||
cost_C = {t: [] for t in range(1, NUM_STEPS + 1)} # capital cost (collects)
|
||||
cost_S = {t: [] for t in range(1, NUM_STEPS + 1)} # steel cost (upgrades b,d)
|
||||
|
||||
# ---- per-city logic -----------------------------------------------
|
||||
for i in range(N):
|
||||
a_step, a_type = cities[i]
|
||||
|
||||
# initial type at arrival step
|
||||
init = {"H": isH, "F": isF, "M": isM, "N": isMon}
|
||||
m.Add(init[a_type][i, a_step] == 1)
|
||||
# no upgrades at arrival
|
||||
m.Add(hasA[i, a_step] == 0)
|
||||
m.Add(hasB[i, a_step] == 0)
|
||||
m.Add(hasD[i, a_step] == 0)
|
||||
# vats at arrival
|
||||
m.Add(vE[i, a_step] == 1)
|
||||
m.Add(vB[i, a_step] == 1)
|
||||
m.Add(vS[i, a_step] == 1)
|
||||
|
||||
# before arrival: everything zero
|
||||
for t in range(1, a_step):
|
||||
for v in (isH, isF, isM, isMon, hasA, hasB, hasD, vE, vB, vS):
|
||||
m.Add(v[i, t] == 0)
|
||||
if t <= NUM_STEPS:
|
||||
for v in (col, ua, ub, ud, rH, rF, rM, cvE, cvB, cvS, mE, mB, mS, mC):
|
||||
m.Add(v[i, t] == 0)
|
||||
|
||||
# action + transition logic for active steps
|
||||
for t in range(a_step, NUM_STEPS + 1):
|
||||
P = present[i, t]
|
||||
ren = m.NewBoolVar("") # any renovation this step
|
||||
m.Add(ren == rH[i, t] + rF[i, t] + rM[i, t])
|
||||
no_ren = m.NewBoolVar("")
|
||||
m.Add(no_ren == 1 - ren)
|
||||
|
||||
# exactly one action while present
|
||||
m.Add(
|
||||
col[i, t]
|
||||
+ ua[i, t]
|
||||
+ ub[i, t]
|
||||
+ ud[i, t]
|
||||
+ rH[i, t]
|
||||
+ rF[i, t]
|
||||
+ rM[i, t]
|
||||
== P
|
||||
)
|
||||
|
||||
# renovation must change type (renovate-to-X requires not-X now)
|
||||
m.Add(isH[i, t] == 0).OnlyEnforceIf(rH[i, t])
|
||||
m.Add(isF[i, t] == 0).OnlyEnforceIf(rF[i, t])
|
||||
m.Add(isM[i, t] == 0).OnlyEnforceIf(rM[i, t])
|
||||
|
||||
# upgrade legality
|
||||
m.Add(hasA[i, t] == 0).OnlyEnforceIf(ua[i, t]) # can't re-acquire
|
||||
m.Add(hasB[i, t] == 0).OnlyEnforceIf(ub[i, t])
|
||||
m.Add(hasD[i, t] == 0).OnlyEnforceIf(ud[i, t])
|
||||
m.Add(isF[i, t] == 1).OnlyEnforceIf(ud[i, t]) # d is foundry-only
|
||||
|
||||
# LLM allowed renovation into metropolis, need to prevent that now
|
||||
m.Add(rM[i, t] == 0)
|
||||
|
||||
# Monument constraints due to maximizing resources and not wanting enemy to get free upgrades
|
||||
m.Add(col[i, t] == 0).OnlyEnforceIf(isMon[i, t])
|
||||
m.Add(ua[i, t] == 0).OnlyEnforceIf(isMon[i, t])
|
||||
m.Add(ub[i, t] == 0).OnlyEnforceIf(isMon[i, t])
|
||||
m.Add(ud[i, t] == 0).OnlyEnforceIf(isMon[i, t])
|
||||
|
||||
# ---- type transition t -> t+1 ----
|
||||
m.Add(isH[i, t + 1] == isH[i, t]).OnlyEnforceIf(no_ren)
|
||||
m.Add(isF[i, t + 1] == isF[i, t]).OnlyEnforceIf(no_ren)
|
||||
m.Add(isM[i, t + 1] == isM[i, t]).OnlyEnforceIf(no_ren)
|
||||
for r, target in ((rH[i, t], isH), (rF[i, t], isF), (rM[i, t], isM)):
|
||||
m.Add(target[i, t + 1] == 1).OnlyEnforceIf(r)
|
||||
m.Add(isF[i, t + 1] == 0).OnlyEnforceIf(rH[i, t])
|
||||
m.Add(isM[i, t + 1] == 0).OnlyEnforceIf(rH[i, t])
|
||||
m.Add(isH[i, t + 1] == 0).OnlyEnforceIf(rF[i, t])
|
||||
m.Add(isM[i, t + 1] == 0).OnlyEnforceIf(rF[i, t])
|
||||
m.Add(isH[i, t + 1] == 0).OnlyEnforceIf(rM[i, t])
|
||||
m.Add(isF[i, t + 1] == 0).OnlyEnforceIf(rM[i, t])
|
||||
|
||||
# ---- upgrade transition t -> t+1 ----
|
||||
# a, b survive renovation and are monotone
|
||||
m.AddMaxEquality(hasA[i, t + 1], [hasA[i, t], ua[i, t]])
|
||||
m.AddMaxEquality(hasB[i, t + 1], [hasB[i, t], ub[i, t]])
|
||||
# d is stripped on renovation, else monotone
|
||||
m.Add(hasD[i, t + 1] == 0).OnlyEnforceIf(ren)
|
||||
d_keep = m.NewBoolVar("")
|
||||
m.AddMaxEquality(d_keep, [hasD[i, t], ud[i, t]])
|
||||
m.Add(hasD[i, t + 1] == d_keep).OnlyEnforceIf(no_ren)
|
||||
|
||||
# ---- collect sub-choices ----
|
||||
fcol = AND(isF[i, t], col[i, t])
|
||||
mcol = AND(isM[i, t], col[i, t])
|
||||
hcol = AND(isH[i, t], col[i, t])
|
||||
# foundry: exactly one vat chosen iff foundry collects
|
||||
m.Add(cvE[i, t] + cvB[i, t] + cvS[i, t] == fcol)
|
||||
# metropolis: pick (2 + hasB) resources (+1 each); else nothing
|
||||
npick = m.NewIntVar(0, 3, "")
|
||||
m.Add(npick == 2 + hasB[i, t]).OnlyEnforceIf(mcol)
|
||||
m.Add(npick == 0).OnlyEnforceIf(mcol.Not())
|
||||
m.Add(mE[i, t] + mB[i, t] + mS[i, t] + mC[i, t] == npick)
|
||||
|
||||
# ================= COSTS =================
|
||||
# foundry & metropolis collect each cost 1 Capital
|
||||
cost_C[t].append(fcol)
|
||||
cost_C[t].append(mcol)
|
||||
# upgrades b,d cost 2 Steel, reduced by 1 if cost-reduction (a) already held
|
||||
for upg in (ub[i, t], ud[i, t]):
|
||||
c = m.NewIntVar(0, 2, "")
|
||||
both = AND(upg, hasA[i, t])
|
||||
m.Add(c == 2).OnlyEnforceIf(upg, hasA[i, t].Not())
|
||||
m.Add(c == 1).OnlyEnforceIf(both)
|
||||
m.Add(c == 0).OnlyEnforceIf(upg.Not())
|
||||
cost_S[t].append(c)
|
||||
|
||||
# ================= GAINS =================
|
||||
# Hub collect: +2 Capital (+1 more if collect-bonus b)
|
||||
hub_gain = m.NewIntVar(0, 3, "")
|
||||
m.Add(hub_gain == 2 + hasB[i, t]).OnlyEnforceIf(hcol)
|
||||
m.Add(hub_gain == 0).OnlyEnforceIf(hcol.Not())
|
||||
gain_C[t].append(hub_gain)
|
||||
|
||||
# Metropolis collect: +1 per pick
|
||||
gain_E[t].append(mE[i, t])
|
||||
gain_B[t].append(mB[i, t])
|
||||
gain_S[t].append(mS[i, t])
|
||||
gain_C[t].append(mC[i, t])
|
||||
|
||||
# Foundry collect: gain chosen vat's value as that resource
|
||||
gEf = m.NewIntVar(0, max_vat, "")
|
||||
gBf = m.NewIntVar(0, max_vat, "")
|
||||
gSf = m.NewIntVar(0, max_vat, "")
|
||||
m.AddMultiplicationEquality(gEf, [cvE[i, t], vE[i, t]])
|
||||
m.AddMultiplicationEquality(gBf, [cvB[i, t], vB[i, t]])
|
||||
m.AddMultiplicationEquality(gSf, [cvS[i, t], vS[i, t]])
|
||||
gain_E[t].append(gEf)
|
||||
gain_B[t].append(gBf)
|
||||
gain_S[t].append(gSf)
|
||||
|
||||
# Collect Bonus (b): adds +1 to the amount a Collect gives. For a
|
||||
# foundry that means +1 of the collected resource (vat value + 1),
|
||||
# the same uniform "+1 to what Collect gives" rule as Hub/Metro.
|
||||
gain_E[t].append(AND(cvE[i, t], hasB[i, t]))
|
||||
gain_B[t].append(AND(cvB[i, t], hasB[i, t]))
|
||||
gain_S[t].append(AND(cvS[i, t], hasB[i, t]))
|
||||
|
||||
# ---- vat update producing vat[i, t+1] ----
|
||||
# increment added to the two non-collected vats (1, or 2 with upgrade d)
|
||||
inc = m.NewIntVar(1, 2, "")
|
||||
m.Add(inc == 1 + hasD[i, t])
|
||||
|
||||
# vat_next = result of this step's action (only meaningful if foundry)
|
||||
vEn = m.NewIntVar(0, max_vat, "")
|
||||
vBn = m.NewIntVar(0, max_vat, "")
|
||||
vSn = m.NewIntVar(0, max_vat, "")
|
||||
# collect E: E->0, B,S += inc
|
||||
m.Add(vEn == 0).OnlyEnforceIf(cvE[i, t])
|
||||
m.Add(vBn == vB[i, t] + inc).OnlyEnforceIf(cvE[i, t])
|
||||
m.Add(vSn == vS[i, t] + inc).OnlyEnforceIf(cvE[i, t])
|
||||
# collect B
|
||||
m.Add(vBn == 0).OnlyEnforceIf(cvB[i, t])
|
||||
m.Add(vEn == vE[i, t] + inc).OnlyEnforceIf(cvB[i, t])
|
||||
m.Add(vSn == vS[i, t] + inc).OnlyEnforceIf(cvB[i, t])
|
||||
# collect S
|
||||
m.Add(vSn == 0).OnlyEnforceIf(cvS[i, t])
|
||||
m.Add(vEn == vE[i, t] + inc).OnlyEnforceIf(cvS[i, t])
|
||||
m.Add(vBn == vB[i, t] + inc).OnlyEnforceIf(cvS[i, t])
|
||||
# foundry but not collecting (upgrade / renovate-away): vats unchanged
|
||||
f_noncollect = AND(isF[i, t], col[i, t].Not())
|
||||
m.Add(vEn == vE[i, t]).OnlyEnforceIf(f_noncollect)
|
||||
m.Add(vBn == vB[i, t]).OnlyEnforceIf(f_noncollect)
|
||||
m.Add(vSn == vS[i, t]).OnlyEnforceIf(f_noncollect)
|
||||
|
||||
# assign vat[i, t+1]:
|
||||
# renovate-to-foundry -> reset to 1
|
||||
# continuing foundry -> vat_next
|
||||
# otherwise (not foundry next) -> 0
|
||||
cont_F = AND(isF[i, t], no_ren) # stays a foundry next step
|
||||
for vnext, vn in (
|
||||
(vE[i, t + 1], vEn),
|
||||
(vB[i, t + 1], vBn),
|
||||
(vS[i, t + 1], vSn),
|
||||
):
|
||||
m.Add(vnext == 1).OnlyEnforceIf(rF[i, t])
|
||||
m.Add(vnext == vn).OnlyEnforceIf(cont_F)
|
||||
m.Add(isF[i, t + 1] == 0).OnlyEnforceIf(
|
||||
rF[i, t].Not(), cont_F.Not()
|
||||
) # tautology guard
|
||||
not_F_next = isF[i, t + 1].Not()
|
||||
m.Add(vE[i, t + 1] == 0).OnlyEnforceIf(not_F_next)
|
||||
m.Add(vB[i, t + 1] == 0).OnlyEnforceIf(not_F_next)
|
||||
m.Add(vS[i, t + 1] == 0).OnlyEnforceIf(not_F_next)
|
||||
|
||||
# ---- resource pool recursion --------------------------------------
|
||||
E = {1: m.NewIntVar(initial[0], initial[0], "E1")}
|
||||
B = {1: m.NewIntVar(initial[1], initial[1], "B1")}
|
||||
S = {1: m.NewIntVar(initial[2], initial[2], "S1")}
|
||||
C = {1: m.NewIntVar(initial[3], initial[3], "C1")}
|
||||
for t in range(1, NUM_STEPS + 1):
|
||||
E[t + 1] = m.NewIntVar(0, max_res, f"E_{t + 1}")
|
||||
B[t + 1] = m.NewIntVar(0, max_res, f"B_{t + 1}")
|
||||
S[t + 1] = m.NewIntVar(0, max_res, f"S_{t + 1}")
|
||||
C[t + 1] = m.NewIntVar(0, max_res, f"C_{t + 1}")
|
||||
# costs are paid from the START-of-step pool (must work out before gains)
|
||||
m.Add(C[t] - sum(cost_C[t]) >= 0)
|
||||
m.Add(S[t] - sum(cost_S[t]) >= 0)
|
||||
# next pool = start - costs + gains
|
||||
m.Add(E[t + 1] == E[t] + sum(gain_E[t]))
|
||||
m.Add(B[t + 1] == B[t] + sum(gain_B[t]))
|
||||
m.Add(S[t + 1] == S[t] - sum(cost_S[t]) + sum(gain_S[t]))
|
||||
m.Add(C[t + 1] == C[t] - sum(cost_C[t]) + sum(gain_C[t]))
|
||||
|
||||
finalE, finalB, finalS = E[NUM_STEPS + 1], B[NUM_STEPS + 1], S[NUM_STEPS + 1]
|
||||
|
||||
# ---- Phase 1: real per-resource ceilings (fast LINEAR maximisations) ----
|
||||
# The triple product E*B*S has a very loose relaxation, so proving optimality
|
||||
# directly is slow. We first find the true max each resource can reach on its
|
||||
# own (a linear objective, solved to optimality quickly), then clamp the final
|
||||
# pools to those ceilings. This tightens the product's propagation enough to
|
||||
# prove optimality, and is valid because no feasible solution can exceed an
|
||||
# individual resource's standalone maximum.
|
||||
def _ceiling(var):
|
||||
s = cp_model.CpSolver()
|
||||
s.parameters.max_time_in_seconds = 20.0
|
||||
s.parameters.num_search_workers = num_workers
|
||||
m.Maximize(var)
|
||||
st = s.Solve(m)
|
||||
return (
|
||||
int(s.ObjectiveValue())
|
||||
if st in (cp_model.OPTIMAL, cp_model.FEASIBLE)
|
||||
else max_res
|
||||
)
|
||||
|
||||
capE = _ceiling(finalE)
|
||||
capB = _ceiling(finalB)
|
||||
capS = _ceiling(finalS)
|
||||
m.Add(finalE <= capE)
|
||||
m.Add(finalB <= capB)
|
||||
m.Add(finalS <= capS)
|
||||
|
||||
# ======================================================================
|
||||
# OBJECTIVE IS SET HERE -- maximise Electrum * Brass * Steel (post step 5)
|
||||
# To change the objective, edit the three "final" pools and/or the product
|
||||
# below. (finalE/finalB/finalS are the pools after step 5's gains.)
|
||||
# ======================================================================
|
||||
## NOTE: product can be changed here
|
||||
prodEB = m.NewIntVar(0, capE * capB, "prodEB")
|
||||
m.AddMultiplicationEquality(prodEB, [finalE, finalB])
|
||||
obj = m.NewIntVar(0, capE * capB * capS, "obj")
|
||||
m.AddMultiplicationEquality(obj, [prodEB, finalS])
|
||||
m.Maximize(obj)
|
||||
|
||||
# ---- Phase 2: solve the product to optimality ----
|
||||
solver = cp_model.CpSolver()
|
||||
solver.parameters.max_time_in_seconds = time_limit
|
||||
solver.parameters.num_search_workers = num_workers
|
||||
status = solver.Solve(m)
|
||||
|
||||
if verbose:
|
||||
print(f"(resource ceilings used: E<={capE} B<={capB} S<={capS})")
|
||||
_report(
|
||||
solver,
|
||||
status,
|
||||
cities,
|
||||
N,
|
||||
isH,
|
||||
isF,
|
||||
isM,
|
||||
isMon,
|
||||
col,
|
||||
ua,
|
||||
ub,
|
||||
ud,
|
||||
rH,
|
||||
rF,
|
||||
rM,
|
||||
cvE,
|
||||
cvB,
|
||||
cvS,
|
||||
mE,
|
||||
mB,
|
||||
mS,
|
||||
mC,
|
||||
hasA,
|
||||
hasB,
|
||||
hasD,
|
||||
vE,
|
||||
vB,
|
||||
vS,
|
||||
E,
|
||||
B,
|
||||
S,
|
||||
C,
|
||||
finalE,
|
||||
finalB,
|
||||
finalS,
|
||||
)
|
||||
return solver, status
|
||||
|
||||
|
||||
def _report(
|
||||
solver,
|
||||
status,
|
||||
cities,
|
||||
N,
|
||||
isH,
|
||||
isF,
|
||||
isM,
|
||||
isMon,
|
||||
col,
|
||||
ua,
|
||||
ub,
|
||||
ud,
|
||||
rH,
|
||||
rF,
|
||||
rM,
|
||||
cvE,
|
||||
cvB,
|
||||
cvS,
|
||||
mE,
|
||||
mB,
|
||||
mS,
|
||||
mC,
|
||||
hasA,
|
||||
hasB,
|
||||
hasD,
|
||||
vE,
|
||||
vB,
|
||||
vS,
|
||||
E,
|
||||
B,
|
||||
S,
|
||||
C,
|
||||
finalE,
|
||||
finalB,
|
||||
finalS,
|
||||
):
|
||||
print("status:", solver.StatusName(status))
|
||||
if status not in (cp_model.OPTIMAL, cp_model.FEASIBLE):
|
||||
return
|
||||
typ_name = {}
|
||||
for i in range(N):
|
||||
for t in range(1, NUM_STEPS + 1):
|
||||
if solver.Value(isH[i, t]):
|
||||
typ_name[i, t] = "Hub"
|
||||
elif solver.Value(isF[i, t]):
|
||||
typ_name[i, t] = "Foundry"
|
||||
elif solver.Value(isM[i, t]):
|
||||
typ_name[i, t] = "Metro"
|
||||
elif solver.Value(isMon[i, t]):
|
||||
typ_name[i, t] = "Monument"
|
||||
else:
|
||||
typ_name[i, t] = "-"
|
||||
|
||||
def action_str(i, t):
|
||||
if solver.Value(col[i, t]):
|
||||
if typ_name[i, t] == "Foundry":
|
||||
v = (
|
||||
"E"
|
||||
if solver.Value(cvE[i, t])
|
||||
else "B"
|
||||
if solver.Value(cvB[i, t])
|
||||
else "S"
|
||||
)
|
||||
return f"Collect vat {v}"
|
||||
if typ_name[i, t] == "Metro":
|
||||
picks = []
|
||||
for nm, var in (("E", mE), ("B", mB), ("S", mS), ("C", mC)):
|
||||
picks += [nm] * solver.Value(var[i, t])
|
||||
return "Collect {" + ",".join(picks) + "}"
|
||||
return "Collect (+Capital)"
|
||||
if solver.Value(ua[i, t]):
|
||||
return "Upgrade a (cost-reduction)"
|
||||
if solver.Value(ub[i, t]):
|
||||
return "Upgrade b (collect-bonus)"
|
||||
if solver.Value(ud[i, t]):
|
||||
return "Upgrade d (vat-increment)"
|
||||
if solver.Value(rH[i, t]):
|
||||
return "Renovate -> Hub"
|
||||
if solver.Value(rF[i, t]):
|
||||
return "Renovate -> Foundry"
|
||||
if solver.Value(rM[i, t]):
|
||||
return "Renovate -> Metro"
|
||||
return "(inactive)"
|
||||
|
||||
print("\nPer-step pools (start of step):")
|
||||
print(" step: E B S C")
|
||||
for t in range(1, NUM_STEPS + 2):
|
||||
label = f"after5" if t == NUM_STEPS + 1 else f"start {t}"
|
||||
print(
|
||||
f" {label:>8}: {solver.Value(E[t]):3} {solver.Value(B[t]):3} "
|
||||
f"{solver.Value(S[t]):3} {solver.Value(C[t]):3}"
|
||||
)
|
||||
|
||||
print("\nActions:")
|
||||
for i in range(N):
|
||||
a_step, a_type = cities[i]
|
||||
print(f" City {i} (arrives step {a_step} as {a_type}):")
|
||||
for t in range(a_step, NUM_STEPS + 1):
|
||||
ups = "".join(
|
||||
n
|
||||
for n, h in (("a", hasA), ("b", hasB), ("d", hasD))
|
||||
if solver.Value(h[i, t])
|
||||
)
|
||||
extra = (
|
||||
f" vats(E{solver.Value(vE[i, t])},B{solver.Value(vB[i, t])},S{solver.Value(vS[i, t])})"
|
||||
if typ_name[i, t] == "Foundry"
|
||||
else ""
|
||||
)
|
||||
print(
|
||||
f" step {t}: [{typ_name[i, t]:7}] {action_str(i, t):28}"
|
||||
f" upg[{ups}]{extra}"
|
||||
)
|
||||
|
||||
fe, fb, fs = solver.Value(finalE), solver.Value(finalB), solver.Value(finalS)
|
||||
print(f"\nFINAL E={fe} B={fb} S={fs} product = {fe * fb * fs}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solve()
|
||||
9
pyproject.toml
Normal file
9
pyproject.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[project]
|
||||
name = "solve"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"ortools>=9.15.6755",
|
||||
]
|
||||
217
uv.lock
Normal file
217
uv.lock
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13"
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.14' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.14' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version < '3.14' and sys_platform == 'win32'",
|
||||
"python_full_version < '3.14' and sys_platform == 'emscripten'",
|
||||
"python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "absl-py"
|
||||
version = "2.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/64/c7/8de93764ad66968d19329a7e0c147a2bb3c7054c554d4a119111b8f9440f/absl_py-2.4.0.tar.gz", hash = "sha256:8c6af82722b35cf71e0f4d1d47dcaebfff286e27110a99fc359349b247dfb5d4", size = 116543, upload-time = "2026-01-28T10:17:05.322Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/a6/907a406bb7d359e6a63f99c313846d9eec4f7e6f7437809e03aa00fa3074/absl_py-2.4.0-py3-none-any.whl", hash = "sha256:88476fd881ca8aab94ffa78b7b6c632a782ab3ba1cd19c9bd423abc4fb4cd28d", size = 135750, upload-time = "2026-01-28T10:17:04.19Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "immutabledict"
|
||||
version = "4.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1d/e6/718471048fea0366c3e3d1df3acfd914ca66d571cdffcf6d37bbcd725708/immutabledict-4.3.1.tar.gz", hash = "sha256:f844a669106cfdc73f47b1a9da003782fb17dc955a54c80972e0d93d1c63c514", size = 7806, upload-time = "2026-02-15T10:32:34.668Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/ce/f9018bf69ae91b273b6391a095e7c93fa5e1617f25b6ba81ad4b20c9df10/immutabledict-4.3.1-py3-none-any.whl", hash = "sha256:c9facdc0ff30fdb8e35bd16532026cac472a549e182c94fa201b51b25e4bf7bf", size = 5000, upload-time = "2026-02-15T10:32:33.672Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ortools"
|
||||
version = "9.15.6755"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "absl-py" },
|
||||
{ name = "immutabledict" },
|
||||
{ name = "numpy" },
|
||||
{ name = "pandas" },
|
||||
{ name = "protobuf" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/53/e21c54ff10002cc2e2b9748012ffc324ec32ea4acdcc85e190a920ab2766/ortools-9.15.6755-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:27a10474e62c9dceed37cfa0e4845c5ffaf792138ebf5b61483771b96f1290b6", size = 23927705, upload-time = "2026-01-14T15:39:07.29Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/e6/f7019048ffdf41f8a1bff6815b2203cf7b9117ba9e26bf46c4585421d1c4/ortools-9.15.6755-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:076565b803c85c4f87863e0616f537dd37f99c03e6f092e4068404f7b425d2b0", size = 21914246, upload-time = "2026-01-14T15:39:10.584Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/ad/aaacd340918b03e22c42f6ae4a9c72aac09810b4b398e99a7eeee58d9c42/ortools-9.15.6755-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b85bd20259b146abce5e0721ce1bfd8fd273efc904216aa3be178c31b6d34057", size = 27646600, upload-time = "2026-01-14T15:38:04.79Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/b9/28d5efb832190b6edfccc5a703e88e64779c1eda34a42ea96d03307236c0/ortools-9.15.6755-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ebd5aea00374e3aad7a78de59058aca5e871a26a3c385cd0860ef1d685d03c9a", size = 29838741, upload-time = "2026-01-14T15:38:07.945Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/22/ab894b6f846b4b1a89795c1ba966834e56cac394c4cf2b72433909739982/ortools-9.15.6755-cp313-cp313-win_amd64.whl", hash = "sha256:caac1d48b967adb877da2abcaf82c28f0f908a7cc208a6a1bbe01bc69590816c", size = 23908100, upload-time = "2026-01-14T15:39:48.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/53/ada4146ae491d7798c6eb045d93135158c0b66030853c7cd9607768dda59/ortools-9.15.6755-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82b4a8e6e4f9380b453ab5fa4382ea7ee91e628f9b8be89d9ad760b33fca3323", size = 27681510, upload-time = "2026-01-14T15:38:11.033Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/e6/239e96912fc8c4e0e917e72ec413983bc042cd9a0b20c3c6a7e43fc3002b/ortools-9.15.6755-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2d1f2fb2088e8953ccb902e68ffd06032cce0c7dcf7268b6135f3b6c553ca52b", size = 29850935, upload-time = "2026-01-14T15:38:14.595Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/ef/53a172ad12cf0d762b9a5af681b1f13f1b4105b38bf65c2b383d530ed97f/ortools-9.15.6755-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:acdf06a167933307608e7eba23a9490255933504df44c8de5f62c48656c29688", size = 23916963, upload-time = "2026-01-14T15:39:13.282Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/54/ed73ec00369fb6d6c71049d62e4b7c87c918b61f86ddd55a11c20ada395e/ortools-9.15.6755-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a0677270b0cd317a6b8dae42514264eaf5da5756c5bc7215eeea409424577df", size = 21923649, upload-time = "2026-01-14T15:39:16.831Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/e0/ac57dd43eaadd73748bb542b30912e16c7dbf3a75f393f69efb8a1a2f032/ortools-9.15.6755-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:899b92afe3f775ab5867b9a8aa2850f81f2d95232db9b4ceec3456d69e6b8528", size = 27657273, upload-time = "2026-01-14T15:38:18.375Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/e0/11144feb4ddadc491dc9d833d3a2080e6556245f912bebe2c0c7e174f2a1/ortools-9.15.6755-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7181183cdcafe2b0d83ca5505b65048c7953dc7b5ad479361dded607964cc1b3", size = 29843939, upload-time = "2026-01-14T15:38:21.457Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/97/771515ba3a05da3903b7da55a190d9f88f36a08c4bf848852e0ea4e3a731/ortools-9.15.6755-cp314-cp314-win_amd64.whl", hash = "sha256:afabb869e5fabeb704bd8147b22bf8139dee042e55fabd0d447a996428009e0c", size = 24673633, upload-time = "2026-01-14T15:39:51.212Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/99/0932d6d7d6ad326adf68f4ce9063ef07db7e9859859dddbcd200102aedff/ortools-9.15.6755-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9d07cddca201e25e2e219006a9d6cda10c7e9ee2c712c50d19d508f9ed8a888", size = 27682088, upload-time = "2026-01-14T15:38:25.174Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/4d/bd75961e2c82db69bb41dd2c4a82131ca580e997485be2d5f59f8d26f31e/ortools-9.15.6755-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:990838ad66a052e72a50e69da500878710e3420e91717fe88bf3071995caba9e", size = 29851493, upload-time = "2026-01-14T15:38:28.168Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pandas"
|
||||
version = "3.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
{ name = "python-dateutil" },
|
||||
{ name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "6.33.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solve"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "ortools" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "ortools", specifier = ">=9.15.6755" }]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2026.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" },
|
||||
]
|
||||
Loading…
Reference in a new issue