Aria AI Deploy
Deploy Optimization Solver Benchmark Lab
3329027
Raw
History Blame Contribute Delete
6.62 kB
"""Problem instance generators."""
from __future__ import annotations
import math
import random
from typing import Any
from solvbench.features import extract_features
from solvbench.models import ProblemInstance
def generate_instance(problem_type: str, size: str = "medium", seed: int = 42) -> ProblemInstance:
generators = {
"knapsack": _gen_knapsack,
"tsp": _gen_tsp,
"vrp": _gen_vrp,
"job_shop": _gen_job_shop,
"bin_packing": _gen_bin_packing,
"facility_location": _gen_facility_location,
"set_cover": _gen_set_cover,
"assignment": _gen_assignment,
"max_independent_set": _gen_mis,
}
if problem_type not in generators:
raise ValueError(f"Unknown problem type: {problem_type}")
rng = random.Random(seed)
data, label = generators[problem_type](rng, size)
features = extract_features(problem_type, data, size)
instance_id = f"{problem_type}_{size}_s{seed}"
return ProblemInstance(
problem_type=problem_type,
instance_id=instance_id,
label=label,
size=size,
seed=seed,
data=data,
features=features,
known_optimum=data.get("known_optimum"),
)
def _scale_n(base: int, size: str) -> int:
factor = {"small": 0.6, "medium": 1.0, "large": 1.5}.get(size, 1.0)
return max(3, int(base * factor))
def _gen_knapsack(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n = _scale_n(80, size)
weights = [rng.randint(1, 50) for _ in range(n)]
values = [rng.randint(10, 200) for _ in range(n)]
capacity = int(sum(weights) * rng.uniform(0.35, 0.55))
return {
"n_items": n,
"weights": weights,
"values": values,
"capacity": capacity,
}, f"Knapsack ({n} items, capacity {capacity})"
def _gen_tsp(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n = _scale_n(15, size)
coords = [(rng.uniform(0, 100), rng.uniform(0, 100)) for _ in range(n)]
dist = []
for i in range(n):
row = []
for j in range(n):
if i == j:
row.append(0.0)
else:
dx = coords[i][0] - coords[j][0]
dy = coords[i][1] - coords[j][1]
row.append(round(math.hypot(dx, dy), 2))
dist.append(row)
return {
"n_cities": n,
"coordinates": coords,
"distance_matrix": dist,
}, f"TSP ({n} cities)"
def _gen_vrp(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n = _scale_n(20, size)
vehicles = max(2, n // 8)
depot = (50.0, 50.0)
customers = [(rng.uniform(0, 100), rng.uniform(0, 100)) for _ in range(n)]
demands = [rng.randint(1, 15) for _ in range(n)]
capacity = max(demands) * 3
total_demand = sum(demands)
coords = [depot] + customers
dist = []
for i in range(len(coords)):
row = []
for j in range(len(coords)):
if i == j:
row.append(0.0)
else:
dx = coords[i][0] - coords[j][0]
dy = coords[i][1] - coords[j][1]
row.append(round(math.hypot(dx, dy), 2))
dist.append(row)
return {
"n_customers": n,
"n_vehicles": vehicles,
"depot_index": 0,
"coordinates": coords,
"demands": [0] + demands,
"vehicle_capacity": capacity,
"distance_matrix": dist,
"demand_ratio": round(total_demand / (vehicles * capacity), 4),
}, f"VRP ({n} customers, {vehicles} vehicles)"
def _gen_job_shop(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n_jobs = _scale_n(5, size)
n_machines = max(3, n_jobs)
processing_times = []
machine_order = []
for _ in range(n_jobs):
machines = list(range(n_machines))
rng.shuffle(machines)
machine_order.append(machines)
processing_times.append([rng.randint(1, 20) for _ in range(n_machines)])
return {
"n_jobs": n_jobs,
"n_machines": n_machines,
"machine_order": machine_order,
"processing_times": processing_times,
}, f"Job Shop ({n_jobs} jobs × {n_machines} machines)"
def _gen_bin_packing(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n = _scale_n(60, size)
capacity = 100
sizes = [rng.randint(10, 90) for _ in range(n)]
return {
"n_items": n,
"item_sizes": sizes,
"bin_capacity": capacity,
}, f"Bin Packing ({n} items, bin cap {capacity})"
def _gen_facility_location(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
nf = _scale_n(8, size)
nc = _scale_n(25, size)
facilities = [(rng.uniform(0, 100), rng.uniform(0, 100)) for _ in range(nf)]
customers = [(rng.uniform(0, 100), rng.uniform(0, 100)) for _ in range(nc)]
fixed_costs = [rng.randint(500, 2000) for _ in range(nf)]
transport = []
for c in customers:
row = []
for f in facilities:
row.append(round(math.hypot(c[0] - f[0], c[1] - f[1]) * rng.uniform(1.0, 3.0), 2))
transport.append(row)
return {
"n_facilities": nf,
"n_customers": nc,
"facility_coords": facilities,
"customer_coords": customers,
"fixed_costs": fixed_costs,
"transport_costs": transport,
}, f"Facility Location ({nf} sites, {nc} customers)"
def _gen_set_cover(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
ne = _scale_n(40, size)
ns = _scale_n(25, size)
sets = []
for _ in range(ns):
size_set = rng.randint(max(1, ne // 10), max(2, ne // 3))
members = sorted(rng.sample(range(ne), min(size_set, ne)))
sets.append(members)
costs = [rng.randint(1, 50) for _ in range(ns)]
return {
"n_elements": ne,
"n_sets": ns,
"sets": sets,
"costs": costs,
}, f"Set Cover ({ne} elements, {ns} sets)"
def _gen_assignment(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n = _scale_n(15, size)
costs = [[rng.randint(1, 100) for _ in range(n)] for _ in range(n)]
return {
"n_agents": n,
"cost_matrix": costs,
}, f"Assignment ({n}×{n})"
def _gen_mis(rng: random.Random, size: str) -> tuple[dict[str, Any], str]:
n = _scale_n(25, size)
p_edge = 0.25
edges = []
for i in range(n):
for j in range(i + 1, n):
if rng.random() < p_edge:
edges.append([i, j])
return {
"n_vertices": n,
"edges": edges,
}, f"Max Independent Set ({n} vertices, {len(edges)} edges)"