IndexError:在车辆路径问题中执行_get_start_solution时列出索引超出范围

问题描述 投票:0回答:1

我正在研究车辆路径问题的实现,在执行 _get_start_solution 函数时遇到 IndexError。错误发生在解决方案的最终打印语句期间。

详情:

'Traceback (most recent call last):
  File "C:\Users\hajar\Desktop\lns_v_test_epsilon\lns\test_alpha_gamma.py", line 128, in <module>
    main()
  File "C:\Users\hajar\Desktop\lns_v_test_epsilon\lns\test_alpha_gamma.py", line 124, in main
    test(epsilon, gamma, alpha)
  File "C:\Users\hajar\Desktop\lns_v_test_epsilon\lns\test_alpha_gamma.py", line 96, in test
    solution = alg.solve(problem, start_time,type="eps_greedy", method="TS",eps=epsilon, ensemble=[])
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\hajar\Desktop\lns_v_test_epsilon\lns\algorithm.py", line 704, in solve
    start_solution = self._get_start_solution(problem)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\hajar\Desktop\lns_v_test_epsilon\lns\algorithm.py", line 802, in _get_start_solution
    f"Final solution: {solution.routes}, "
  File "C:\Users\hajar\Desktop\lns_v_test_epsilon\lns\solution.py", line 391, in __repr__
    self.earliest[i],
    ~~~~~~~~~~~~~^^^
IndexError: list index out of range'

我的实例中有 30 个客户,但其中一个指数似乎超出了范围。 回溯表明,在最小化车辆后尝试访问路线时出现错误。

这是我的 _get_start_solution 函数的上下文片段:

def _get_start_solution(self, problem):
    """
    Generate an initial solution for the problem by assigning requests to vehicles
    based on vehicle capacity and customer demands.

    Parameters
    ----------
    problem : `Problem`
        The optimization problem containing vehicles and requests.

    Returns
    -------
    solution : `Solution`
        The initial solution object with routes for all vehicles.
    """
    # Initialize the solution object
    solution = Solution(problem)

    num_customers = len(problem.P)  # Number of customers (pickup points)
    print(f"Number of customers: {num_customers}")

    # Default vehicle capacity, adjust if capacity is stored elsewhere in problem
    vehicle_capacity = getattr(problem.vehicles[0], 'capacity', 100)  # Get vehicle capacity from the first vehicle
    print(f"Vehicle capacity: {vehicle_capacity}")

    # Initialize routes and remaining capacities for each vehicle
    routes = []
    capacities = []
    vehicle_id = 0  # Start vehicle IDs from 0

    # Create a list of customers (excluding depot which is assumed to be customer 0)
    customers = list(range(1, num_customers + 1))  # Only customers, not the depot
    print(f"Shuffling customers: {customers}")
    random.shuffle(customers)

    # Create a new route whenever the vehicle is full
    current_route = []
    current_capacity = vehicle_capacity

    # Iterate over the shuffled customers and assign them to vehicles
    for customer_id in customers:
        if customer_id not in problem.P:
            print(f"Customer {customer_id} not found in problem.P")
            continue  # Skip this customer if they do not exist
        # Get the demand of the customer (assuming demand is stored in 'load')
        demand = problem.P[customer_id].load  # Adjust if demand attribute is different
        print(f"Customer {customer_id} demand: {demand}")

        # Check if the current vehicle can accommodate the customer's demand
        if current_capacity >= demand:
            current_route.append(customer_id)
            current_capacity -= demand

            # Remove the customer from the request bank as it is now assigned
            if customer_id in solution.request_bank:
                solution.request_bank.remove(customer_id)
        else:
            # If the current vehicle is full, finalize the current route and start a new one
            if current_route:  # Only append if current_route is not empty
                route = Route(problem, vehicle_id)
                route.route = current_route  # Assign the customers to the route
                routes.append(route)  # Add the completed route to the routes list

            # Start a new route with a new vehicle
            current_route = [customer_id]
            current_capacity = vehicle_capacity - demand

            # Remove the customer from the request bank as it is now assigned
            if customer_id in solution.request_bank:
                solution.request_bank.remove(customer_id)

            # Increment vehicle ID for the next route
            vehicle_id += 1

    # Add the final route (if there are still customers left)
    if current_route:
        route = Route(problem, vehicle_id)
        route.route = current_route  # Assign the customers to the route
        routes.append(route)  # Add the last route to the routes list

    # Check if all requests have been assigned to a route
    if 0 in solution.request_bank:  # Check if depot is in the request bank (shouldn't be)
        solution.request_bank.remove(0)  # Remove depot if present

    if len(solution.request_bank) > 0:
        print(f"Remaining in request bank: {solution.request_bank}")
        raise IndexError("There are not enough vehicles to assign all requests")

    # Filter the routes to include only those that were used
    solution.routes = routes  # Use the routes list created earlier
    print(
         f"Final solution: {solution.routes}, "
         f"Number of routes: {len(solution.routes)}, "
         f"Number of vehicles used: {solution._number_of_used_vehicles()}"
     )
    # Rebuild insert matrices to reflect the current state of the solution
    solution._rebuild_insert_matrices()

    return solution


   def _rebuild_insert_matrices(self):
    """
    (Re)build the insert matrices.

    This method (re)builds _delta_f and _best_insert_position.
    Matrices needed by the insert heuristics.
    """
    # Creating and initializing matrices
    self._delta_f = [[float('inf')]*len(self.routes) for x in range(self.problem.n)]
    self._best_insert_position = [[-1]*len(self.routes) for x in range(self.problem.n)]

    # For each route
    for route_id in self.available_vehicles:
        self._update_best_insert_route(route_id)

我有这个数据:

    B-n31-k5
runtime: 831.782910
 VEHICLE
 NUMBER     CAPACITY
 100000                     100

CUSTOMER
CUST NO.  XCOORD.    YCOORD.    DEMAND

  0             17                76                 0
  1             24            6              25
  2             96            29             3
  3             14            19            13
  4             14            32            17
  5             0            34              16
  6             16           22            9
  7              20           26            22
  8             22            28            10
  9             17            23            16
 10             98            30              8
 11             30            8              3
 12             23             27           16
 13             19             23            16
 14              34            7             10
 15              31             7            24
 16             0            37            16
 17             19            23             15
 18             0             36              14
 19             26             7             5
 20              98              32            12
 21             5               40         2
 22             17             26              18
 23              21             26             20
 24             28              8            15
 25             1             35            8
 26            27             28            22
 27             99             30            15
 28              26             28              10
 29            17            29            13
 30            20            26            19

任何人都可以帮助我确定为什么会发生此 IndexError 以及如何确保所有客户端都正确包含在解决方案中?任何有关有效管理路线的指导将不胜感激!

repr的代码:

    def __repr__(self):
    result = "* Total current cost: %s \n" % self.cost
    result += "* (node: [start, departure_load]):\n"
    for i in range(len(self.route)):
        result += "(%s: [%s, %s]) --> " % (self.route[i],
                                           self.earliest[i],
                                           self.loads[i])
    return result
python heuristics vehicle-routing
1个回答
0
投票

此代码解决了我的问题,无需更改 repr,只需更改 get_start_solution

def _get_start_solution(self, problem):
    """
    Generate an initial solution for the problem by assigning requests to vehicles
    based on vehicle capacity and customer demands.

    Parameters
    ----------
    problem : `Problem`
        The optimization problem containing vehicles and requests.

    Returns
    -------
    solution : `Solution`
        The initial solution object with routes for all vehicles.
    """
    # Initialize the solution object
    solution = Solution(problem)

    num_customers = len(problem.P)  # Number of customers (pickup points)
    print(f"Number of customers: {num_customers}")

    vehicle_capacity = getattr(problem.vehicles[0], 'capacity', 100)  # Get vehicle capacity from the first vehicle
    print(f"Vehicle capacity: {vehicle_capacity}")

    routes = []
    vehicle_id = 0  # Start vehicle IDs from 0

    # Create a list of customers (excluding depot which is assumed to be customer 0)
    customers = list(range(1, num_customers + 1))  # Only customers, not the depot
    print(f"Shuffling customers: {customers}")
    random.shuffle(customers)

    current_route = []
    current_capacity = vehicle_capacity
    current_loads = []  # To keep track of the loads in the current route

    for customer_id in customers:
        if customer_id not in problem.P:
            print(f"Customer {customer_id} not found in problem.P")
            continue  # Skip this customer if they do not exist

        demand = problem.P[customer_id].load  # Assuming demand is stored in 'load'
        print(f"Customer {customer_id} demand: {demand}")

        # Check if the current vehicle can accommodate the customer's demand
        if current_capacity >= demand:
            current_route.append(customer_id)
            current_capacity -= demand
            current_loads.append(demand)  # Track the load for this route

            # Remove the customer from the request bank as it is now assigned
            if customer_id in solution.request_bank:
                solution.request_bank.remove(customer_id)
        else:
            if current_route:  # Only append if current_route is not empty
                route = Route(problem, vehicle_id)
                route.route = current_route
                routes.append(route)

                # Synchronize earliest, latest, and loads with the route length
                route.earliest = [0] * len(current_route)  # Assuming default values for earliest
                route.latest = [0] * len(current_route)    # Assuming default values for latest
                route.loads = current_loads  # Assign the loads

            # Start a new route with a new vehicle
            current_route = [customer_id]
            current_capacity = vehicle_capacity - demand
            current_loads = [demand]  # Reset the load for the new route

            # Remove the customer from the request bank as it is now assigned
            if customer_id in solution.request_bank:
                solution.request_bank.remove(customer_id)

            # Increment vehicle ID for the next route
            vehicle_id += 1

    # Add the final route (if there are still customers left)
    if current_route:
        route = Route(problem, vehicle_id)
        route.route = current_route
        routes.append(route)

        # Synchronize earliest, latest, and loads with the route length
        route.earliest = [0] * len(current_route)
        route.latest = [0] * len(current_route)
        route.loads = current_loads  # Assign the final loads

    # Check if all requests have been assigned to a route
    if 0 in solution.request_bank:  # Check if depot is in the request bank (shouldn't be)
        solution.request_bank.remove(0)

    if len(solution.request_bank) > 0:
        print(f"Remaining in request bank: {solution.request_bank}")
        raise IndexError("There are not enough vehicles to assign all requests")

    solution.routes = routes  # Use the routes list created earlier
    print(
        f"Final solution: {solution.routes}, "
        f"Number of routes: {len(solution.routes)}, "
        f"Number of vehicles used: {solution._number_of_used_vehicles()}"
    )

    # Rebuild insert matrices to reflect the current state of the solution
    solution._rebuild_insert_matrices()

    return solution
© www.soinside.com 2019 - 2024. All rights reserved.