dsc_co / tests /test_solver.py
AceofStades's picture
Upload folder using huggingface_hub
07a9b4f verified
Raw
History Blame Contribute Delete
2.58 kB
import random
import pytest
from server.dsc_environment import _build_tier
from server.solver import EdgeSpec, NodeSpec, Scenario, greedy_cost, optimal_cost
def _trivial_scenario(h: int = 5) -> Scenario:
nodes = (
NodeSpec(id="S0", type="supplier", initial_inventory=100, max_capacity=1000, holding_cost=0.0),
NodeSpec(id="W0", type="warehouse", initial_inventory=0, max_capacity=200, holding_cost=0.0),
NodeSpec(id="R0", type="retail", initial_inventory=0, max_capacity=50, holding_cost=0.0),
)
edges = (
EdgeSpec(src="S0", dst="W0", lead_time=1, unit_cost=1.0, capacity=50),
EdgeSpec(src="W0", dst="R0", lead_time=1, unit_cost=1.0, capacity=50),
)
demand = {"R0": tuple([5] * h)}
return Scenario(
nodes=nodes,
edges=edges,
demand=demand,
horizon=h,
penalty=100.0,
supplier_step_cap=100,
)
class TestOptimalCost:
def test_trivial_closed_form(self):
sc = _trivial_scenario(h=5)
cost = optimal_cost(sc, time_limit=10)
assert cost >= 0.0
assert cost < 1e6
def test_tier1_monotone(self):
for seed in [1, 2, 3]:
sc = _build_tier(1, random.Random(seed))
g = greedy_cost(sc)
o = optimal_cost(sc, time_limit=10)
assert o <= g + 1e-6, f"optimal must be <= greedy, seed {seed}"
def test_tier2_feasible(self):
sc = _build_tier(2, random.Random(7))
o = optimal_cost(sc, time_limit=30)
assert o > 0.0
assert o != float("inf")
class TestCurriculum:
@pytest.mark.parametrize("tier,ns,nw,nr", [(1, 1, 1, 1), (2, 3, 5, 10), (3, 5, 10, 20)])
def test_tier_shapes(self, tier, ns, nw, nr):
sc = _build_tier(tier, random.Random(0))
sups = [n for n in sc.nodes if n.type == "supplier"]
whs = [n for n in sc.nodes if n.type == "warehouse"]
rets = [n for n in sc.nodes if n.type == "retail"]
assert len(sups) == ns
assert len(whs) == nw
assert len(rets) == nr
def test_tier_bipartite_edges(self):
sc = _build_tier(2, random.Random(0))
for e in sc.edges:
src_type = next(n.type for n in sc.nodes if n.id == e.src)
dst_type = next(n.type for n in sc.nodes if n.id == e.dst)
assert (src_type, dst_type) in (("supplier", "warehouse"), ("warehouse", "retail"))
def test_demand_nonnegative(self):
sc = _build_tier(3, random.Random(11))
for r_id, d in sc.demand.items():
assert all(q >= 0 for q in d)