Source code for discrete_optimization.tsptw.parser

#  Copyright (c) 2025 AIRBUS and its affiliates.
#  This source code is licensed under the MIT license found in the
#  LICENSE file in the root directory of this source tree.
import os
from typing import Optional

import numpy as np

from discrete_optimization.datasets import get_data_home
from discrete_optimization.tsptw.problem import TSPTWProblem


[docs] def get_data_available( data_folder: Optional[str] = None, data_home: Optional[str] = None ) -> list[str]: """Get datasets available for tsptw. Params: data_folder: folder where datasets for tsptw whould be find. If None, we look in "tsptw" subdirectory of `data_home`. data_home: root directory for all datasets. Is None, set by default to "~/discrete_optimization_data " """ if data_folder is None: data_home = get_data_home(data_home=data_home) data_folder = f"{data_home}/tsptw/SolomonPotvinBengio" try: datasets = [ os.path.abspath(os.path.join(data_folder, f)) for f in os.listdir(data_folder) ] except FileNotFoundError: datasets = [] return datasets
[docs] def parse_tsptw_file(filepath: str) -> TSPTWProblem: """ Parses a TSP-TW problem file in the specified format. Args: filepath: The path to the TSP-TW instance file. Returns: An instance of the TSPTWProblem class. """ with open(filepath, "r") as f: content = f.read() # Clean the content by removing comments, source tags, and extra whitespace content = content numbers = content.split() if not numbers: raise ValueError("File is empty or contains no parsable data.") # Parse number of nodes num_nodes = int(numbers.pop(0)) # Parse distance matrix if len(numbers) < num_nodes * num_nodes: raise ValueError("File does not contain enough data for the distance matrix.") distance_matrix_list = [] for _ in range(num_nodes): row = [float(numbers.pop(0)) for _ in range(num_nodes)] distance_matrix_list.append(row) distance_matrix = np.array(distance_matrix_list) # Parse time windows if len(numbers) < num_nodes * 2: raise ValueError("File does not contain enough data for the time windows.") time_windows = [] for _ in range(num_nodes): # The file format might have node indices, but we assume order corresponds to node ID # It's safer to just parse the time windows themselves. # We find the next two integers in the list. earliest = int(numbers.pop(0)) latest = int(numbers.pop(0)) time_windows.append((earliest, latest)) return TSPTWProblem( nb_nodes=num_nodes, distance_matrix=distance_matrix, time_windows=time_windows, )