Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tests/parse/test_parse_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
"Route #1: 1 \n Route #2: 6\n ABCDE",
{"routes": [[1], [6]]},
),
(
# Reload "|" character
"Route #1: 1 | 2 \n Route #2: 3",
{"routes": [[1, "|", 2], [3]]},
),
],
)
def test_parse_solution(text, data):
Expand Down
16 changes: 11 additions & 5 deletions vrplib/parse/parse_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

def parse_solution(text: str) -> Solution:
"""
Parses the text of a solution file formatted in VRPLIB style. A solution
consists of routes, which are indexed from 1 to n, and possibly other data.
Parses a VRPLIB-formatted solution text into a dictionary.
- Routes appear as "Route #n: node1 node2 node3..." where nodes can be:
* Integer indices (0-indexed, unlike 1-indexed instance data)
* String markers (e.g., "|" for reload depots).
- Additional metadata as key-value pairs (e.g., "Cost: 123.45")

Parameters
----------
Expand All @@ -18,14 +21,17 @@ def parse_solution(text: str) -> Solution:
Returns
-------
dict
The soluion data.
The soluion data dictionary, containing:
- "routes": list of routes, each route being a list of nodes
- Additional metadata as key-value pairs from the solution
"""
solution: Solution = {"routes": []}

for line in text2lines(text):
if "Route" in line:
route = [int(idx) for idx in line.split(":")[1].split(" ") if idx]
solution["routes"].append(route) # type: ignore
raw_visits = line.split(":")[1].split()
visits = [int(val) if val.isdigit() else val for val in raw_visits]
solution["routes"].append(visits) # type: ignore
elif ":" in line or " " in line: # Split at first colon or whitespace
split_at = ":" if ":" in line else " "
k, v = [word.strip() for word in line.split(split_at, 1)]
Expand Down