mirror of
https://github.com/L-yang-yang/cugenopt.git
synced 2026-05-09 14:22:37 +02:00
Initial commit: cuGenOpt GPU optimization solver
This commit is contained in:
commit
fc5a0ff4af
117 changed files with 25545 additions and 0 deletions
136
benchmark/common/instances.py
Normal file
136
benchmark/common/instances.py
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
"""
|
||||
标准实例解析器 — 从 TSPLIB / CVRPLIB 官方文件读取数据
|
||||
数据文件位于 data/tsplib/ 和 data/cvrplib/
|
||||
"""
|
||||
import math
|
||||
import os
|
||||
|
||||
DATA_ROOT = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data")
|
||||
TSPLIB_DIR = os.path.join(DATA_ROOT, "tsplib")
|
||||
CVRPLIB_DIR = os.path.join(DATA_ROOT, "cvrplib")
|
||||
|
||||
|
||||
def parse_tsp(filepath):
|
||||
"""解析 TSPLIB .tsp 文件(EUC_2D 格式)"""
|
||||
meta = {}
|
||||
coords = []
|
||||
reading_coords = False
|
||||
|
||||
with open(filepath) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line == "NODE_COORD_SECTION":
|
||||
reading_coords = True
|
||||
continue
|
||||
if line in ("EOF", "DISPLAY_DATA_SECTION"):
|
||||
break
|
||||
if reading_coords:
|
||||
parts = line.split()
|
||||
coords.append((float(parts[1]), float(parts[2])))
|
||||
else:
|
||||
if ":" in line:
|
||||
key, val = line.split(":", 1)
|
||||
meta[key.strip()] = val.strip()
|
||||
|
||||
n = int(meta.get("DIMENSION", len(coords)))
|
||||
assert len(coords) == n, f"Expected {n} coords, got {len(coords)}"
|
||||
return {"name": meta.get("NAME", ""), "n": n, "coords": coords}
|
||||
|
||||
|
||||
def parse_vrp(filepath):
|
||||
"""解析 CVRPLIB .vrp 文件"""
|
||||
meta = {}
|
||||
coords = []
|
||||
demands = []
|
||||
section = None
|
||||
|
||||
with open(filepath) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line == "NODE_COORD_SECTION":
|
||||
section = "coord"
|
||||
continue
|
||||
elif line == "DEMAND_SECTION":
|
||||
section = "demand"
|
||||
continue
|
||||
elif line in ("DEPOT_SECTION", "EOF"):
|
||||
section = None
|
||||
continue
|
||||
|
||||
if section == "coord":
|
||||
parts = line.split()
|
||||
coords.append((float(parts[1]), float(parts[2])))
|
||||
elif section == "demand":
|
||||
parts = line.split()
|
||||
demands.append(int(parts[1]))
|
||||
elif ":" in line:
|
||||
key, val = line.split(":", 1)
|
||||
meta[key.strip()] = val.strip()
|
||||
|
||||
n = int(meta.get("DIMENSION", len(coords)))
|
||||
capacity = int(meta.get("CAPACITY", 0))
|
||||
name = meta.get("NAME", "")
|
||||
|
||||
comment = meta.get("COMMENT", "")
|
||||
optimal = 0
|
||||
if "Optimal value:" in comment:
|
||||
optimal = int(comment.split("Optimal value:")[-1].strip().rstrip(")"))
|
||||
|
||||
return {
|
||||
"name": name,
|
||||
"n": n,
|
||||
"coords": coords,
|
||||
"demands": demands,
|
||||
"capacity": capacity,
|
||||
"optimal": optimal,
|
||||
}
|
||||
|
||||
|
||||
def euc2d_dist_matrix(coords):
|
||||
"""EUC_2D 距离矩阵(四舍五入到整数,与 TSPLIB 标准一致)"""
|
||||
n = len(coords)
|
||||
dist = [[0] * n for _ in range(n)]
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
dx = coords[i][0] - coords[j][0]
|
||||
dy = coords[i][1] - coords[j][1]
|
||||
dist[i][j] = round(math.sqrt(dx * dx + dy * dy))
|
||||
return dist
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 预定义实例列表(文件名 → 已知最优)
|
||||
# ============================================================
|
||||
|
||||
TSP_INSTANCES = [
|
||||
{"file": "eil51.tsp", "optimal": 426},
|
||||
{"file": "eil76.tsp", "optimal": 538},
|
||||
{"file": "kroA100.tsp", "optimal": 21282},
|
||||
{"file": "ch150.tsp", "optimal": 6528},
|
||||
{"file": "tsp225.tsp", "optimal": 3916},
|
||||
{"file": "lin318.tsp", "optimal": 42029},
|
||||
{"file": "pcb442.tsp", "optimal": 50778},
|
||||
]
|
||||
|
||||
VRP_INSTANCES = [
|
||||
{"file": "A-n32-k5.vrp", "optimal": 784, "n_vehicles": 5},
|
||||
]
|
||||
|
||||
|
||||
def load_tsp(entry):
|
||||
"""加载一个 TSP 实例"""
|
||||
data = parse_tsp(os.path.join(TSPLIB_DIR, entry["file"]))
|
||||
data["optimal"] = entry["optimal"]
|
||||
return data
|
||||
|
||||
|
||||
def load_vrp(entry):
|
||||
"""加载一个 VRP 实例"""
|
||||
data = parse_vrp(os.path.join(CVRPLIB_DIR, entry["file"]))
|
||||
data["optimal"] = entry["optimal"]
|
||||
data["n_vehicles"] = entry["n_vehicles"]
|
||||
return data
|
||||
Loading…
Add table
Add a link
Reference in a new issue