Vehicle routing problems with time windows (VRPTW) learning practice and base case code development

Vehicle Routing Problems with Time Windows (VRPTW) is a well-known combinatorial optimization problem that involves effectively arranging the paths of multiple vehicles under the constraints of a limited time window to meet customer needs.

In VRPTW, it is assumed that there is a central warehouse and a group of customer nodes, each node has a specific demand, service time window and time window width. The goal of the problem is to find a set of optimal paths subject to the following constraints:

  • Each node can only serve during its time window.
  • The vehicle departs from the depot and returns to the depot within the vehicle's maximum travel distance and capacity limits.
  • All customer requirements are met.

VRPTW is an NP-hard problem, and it is difficult to obtain an exact solution in polynomial time. Therefore, heuristic and metaheuristic algorithms are often used to approximate the solution.

The following are some commonly used methods to solve VRPTW:

  1. Heuristic-based methods: These methods use heuristic rules to guide path construction. For example, nearest neighbor rule, farthest insertion rule, optimal insertion rule, etc. They build the path step by step, selecting one node for insertion at a time, until all nodes have been inserted into the path.

  2. Genetic Algorithms and Evolutionary Algorithms: These algorithms use genetic codes and evolutionary operations (such as crossover, mutation) to perform global searches. The quality of paths is optimized generation by generation by exploiting properties of good solutions.

  3. Tabu search algorithm: This algorithm avoids repeated searches for similar solutions by jumping out of the search process for local optimal solutions and based on tabu lists and tabu strategies.

  4. Simulated Annealing Algorithm: This is a stochastic search optimization algorithm that simulates the behavior of substances during annealing. By gradually reducing the temperature and the probability of accepting inferior solutions, the global optimal solution is gradually searched.

  5. Other meta-heuristic algorithms: such as ant colony algorithm, particle swarm algorithm, artificial immune algorithm, etc. These algorithms simulate the behavior and phenomena of nature and are used for search and optimization problems.

The solution method of VRPTW requires selecting an appropriate algorithm based on the scale and complexity of the problem. Solving VRPTW is not only about finding the optimal path, but also requires path planning, resource allocation and optimal scheduling to improve efficiency and meet time constraints.

Different solution methods have different principles and different applicable scenarios. Here is a brief summary and analysis:

  1. Heuristic algorithm: Heuristic algorithm is an experience-based method that guides the construction of paths by designing some rules or strategies. For example, the nearest neighbor rule selects the next node closest to the current node for insertion. Their advantages include simplicity and ease of implementation, high computational efficiency, and the ability to find near-optimal solutions in a short time. However, heuristic algorithms are often limited to local searches, may fall into suboptimal solutions, and are not guaranteed to find the global optimal solution.

  2. Genetic algorithm and evolutionary algorithm: Genetic algorithm simulates the biological evolution process in nature and uses evolutionary operations such as crossover and mutation to conduct a global search for paths. The advantage is that it can search multiple solutions in parallel and avoid falling into a local optimal solution. However, since genetic algorithms require a large number of solution evaluation and selection operations, the computational complexity is high and there is no guarantee of obtaining the optimal solution.

  3. Tabu search algorithm: Tabu search avoids falling into local optimal solutions and explores a broader search space by memorizing search history and tabu strategies. Its advantage is that it has strong global search capabilities and can find better solutions within limited search time. However, the design of when the tabu search algorithm chooses to unblock and the update strategy of the tabu table need to be carefully adjusted. Different problems may require different taboo ideas.

  4. Simulated annealing algorithm: The simulated annealing algorithm simulates the temperature drop process of an object during annealing by using random perturbation and the strategy of accepting inferior solutions, which helps to jump out of the local optimal solution. Its advantage is that it has strong global search capabilities and can explore more extensively in the search space. However, the effect of the simulated annealing algorithm is highly dependent on the settings of the annealing parameters. For complex problems, it may take a long time to search to find a better solution.

  5. Other meta-heuristic algorithms: ant colony algorithm, particle swarm algorithm, artificial immune algorithm and other meta-heuristic algorithms perform path search and optimization based on simulated behaviors or phenomena in nature. They have strong global search capabilities and adaptability. However, their parameter settings are relatively complex and computational overhead is high, which may not be applicable to situations with larger problem sizes.

Appropriate solution methods need to be selected based on specific problems and needs. For simple tasks and smaller problem sizes, heuristics may be sufficient; for complex tasks and large-scale problems, evolutionary algorithms, tabu search, or metaheuristics may be more suitable. In addition, multiple algorithms can be combined to solve problems, such as heuristic algorithms and tabu search, to give full play to their respective advantages.

Recently, there was a small problem that may be consistent with this solution. I wanted to take some time to look at the knowledge related to VRPTW and do some practical work based on actual data.

The example data set looks like this:

Parameter definition:

capacity = 200
temperature=1000
alpha=0.99
speed=1
HUGE=99999999
early_unit_cost=0.2
late_unit_cost=0.5
distance_unit_cost=1
best_sol=None

Corresponding class definition:

class Node:
    def __init__(self):
        self.name = None
        self.x = None
        self.y = None
        self.demand = None
        self.ready = None
        self.due = None
        self.service = None


class Sol:
    def __init__(self):
        self.path = []
        self.node = []
        self.cost=None

Cost calculation:

def get_cost(sol):
    total_cost=0
    distance_cost=0
    early_cost=0
    late_cost=0
    sum_demand=0
    now_time=0
    for i in range(len(sol.path)):
        if i==0:
            continue
        distance=get_distance(sol.path[i-1].x,sol.path[i-1].y,sol.path[i].x,sol.path[i].y)
        distance_cost+=distance*distance_unit_cost
        now_time+=distance/speed
        sum_demand+=sol.path[i].demand
        if sum_demand>capacity:
            total_cost+=HUGE
        if now_time<sol.path[i].ready:
            early_cost+=(sol.path[i].ready-now_time)*early_unit_cost
            now_time=sol.path[i].ready
        if now_time>sol.path[i].due:
            late_cost += (now_time-sol.path[i].due) * late_unit_cost
        now_time+=sol.path[i].service
        if sol.path[i].name==0:
            now_time=0
            sum_demand=0
    total_cost+=distance_cost+early_cost+late_cost
    sol.cost=total_cost
    return total_cost

Local search:

def local_search(sol):
    global best_sol
    temp_sol=copy.deepcopy(sol)
    temp2_sol=copy.deepcopy(sol)
    for i in range(10):
        change(temp2_sol)
        if get_cost(temp2_sol)<get_cost(temp_sol):
            temp_sol=copy.deepcopy(temp2_sol)
    c1=get_cost(temp_sol)
    c2=get_cost(sol)
    if c1<c2:
        if c1<best_sol.cost:
            best_sol=temp_sol
        sol=temp_sol
    else:
        if np.exp((c2-c1)/temperature)<random.random():
            sol = temp_sol
    return sol

Example execution:

sol=read_data()
init_code(sol)
print(get_cost(sol))
best_sol=copy.deepcopy(sol)
cost=[]
for i in tqdm(range(2000)):
    sol=local_search(sol)
    cost.append(sol.cost)
    temperature*=alpha
plt.clf()
plt.plot(cost)
plt.savefig("cost.png")
plot(best_sol)
print([best_sol.path[i].name for i in range(len(best_sol.path))])

The terminal output looks like this:

The recorded visualization of the path search is as follows:

The cost calculation curve is as follows:

The cost tends to stabilize as the search iterates.

Guess you like

Origin blog.csdn.net/Together_CZ/article/details/132580802