蚁群算法解决CVRP

该博客探讨了如何运用蚁群算法解决车辆路线问题(CVRP),旨在找到物流中心向多个客户配送货物的最优路径。在考虑车辆数量、承载限制、行驶里程等因素下,目标是最大化配送订单并最小化总里程。博客提供了具体问题的数据(5辆载重8T、最大行驶距离50KM的车辆,需向20个客户配送)和一个简单的Python实现作为参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蚁群算法解决CVRP

问题

​ 通过实际案例描述,根据配送点和业务需求量,进行最优路线的计算。由物流中心点出发,配送多个客户点后再回到起点,根据车辆数量,承载限制,不同车辆服务成本、运行里程限制等条件选择最优运输路径(总里程最短),使成本最小化,配送订单最大化,满载率最大化(如由一个配送中心向各个销售点配送货物,通过算法确定配送中心每辆车的配送方案,包括配送至哪个客户,配送量,下一个配送目的地)。

问题数据及说明

​ 某物流中心有5台配送车辆,车辆的最大载重均为8T,一次配送的最大行驶距离都为50KM,需要向20个客户送货,物流中心和20个客户的坐标及其客户的需求量随机产生,其中,物流中心的坐标为(14.2KM,13.1km),要求合理安排车辆的配送路线和载重量,使配送总里程最短

客户点横坐标x(km)纵坐标y(km)需求量q(t)
112.88.50.1
218.43.40.4
315.416.61.2
418.915.21.5
515.511.60.8
63.910.61.3
710.67.61.7
88.68.40.6
912.52.11.2
1013.85.20.4
116.716.90.9
1214.82.61.3
131.88.71.3
1417.1111.9
157.411.7
160.22.81.1
1711.919.81.5
1813.215.11.6
196.45.61.7
209.614.81.5

说明:各客户相互之间和物流中心与客户之间的距离均采用直线距离

python代码(代码不好,仅供参考)

import random
import copy
import sys
'''
ALPHA:信息启发因子,值越大,则蚂蚁选择之前走过的路径可能性就越大
      ,值越小,则蚁群搜索范围就会减少,容易陷入局部最优
BETA:Beta值越大,蚁群越就容易选择局部较短路径,这时算法收敛速度会
     加快,但是随机性不高,容易得到局部的相对最优
RH0:挥发率
Q : 每条路径上释放的信息素Q / 路径长度 
'''
(ALPHA, BETA, RHO, Q) = (0.7, 2.5, 0.20, 100.0)
# 城市数,蚁群
(city_num, ant_num) = (21, 21)
distance_x = [14.2,12.8, 18.4, 15.4,18.9,15.5,3.9,10.6,8.6,12.5,13.8,6.7,14.8,1.8,17.1,7.4,0.2,11.9,13.2,6.4,9.6]
distance_y = [13.1,8.5, 3.4, 16.6, 15.2, 11.6, 10.6, 7.6, 8.4, 2.1, 5.2, 16.9, 2.6, 8.7, 11, 1, 2.8, 19.8, 15.1, 5.6, 14.8]
need = [0,0.1,0.4,1.2,1.5,0.8,1.3,1.7,0.6,1.2,0.4,0.9,1.3,1.3,1.9,1.7,1.1,1.5,1.6,1.7,1.5] #需求量
# 城市距离和信息素
distance_graph = [[0.0 for col in range(city_num)] for raw in range(city_num)]
pheromone_graph = [[1.0 for col in range(city_num)] for raw in range(city_num)]
class Ant(object):
    # 初始化
    def __init__(self, ID):

        self.ID = ID  # ID
        self.__clean_data()  # 随机初始化出生点

    # 初始数据
    def __clean_data(self):

        self.path = []  # 当前蚂蚁的路径
        self.total_distance = 0.0  # 当前路径的总距离
        self.move_count = 0  # 移动次数
        self.current_city = -1  # 当前停留的城市
        self.open_table_city = [True for i in range(city_num)]  # 探索城市的状态

        city_index = 0  # 随机初始出生点
        self.current_city = city_index
        self.path.append(city_index)
        self.open_table_city[city_index] = False
        self.move_count = 1

    # 选择下一个城市
    def __choice_next_city(self):

        next_city = -1
        select_citys_prob = [0.0 for i in range(city_num)]  # 存储去下个城市的概率
        total_prob = 0.0

        # 获取去下一个城市的概率
        for i in range(city_num):
            if self.open_table_city[i]:
                try:
                    # 计算概率:与信息素浓度成正比,与距离成反比
                    select_citys_prob[i] = pow(pheromone_graph[self.current_city][i], ALPHA) * pow(
                        (1.0 / distance_graph[self.current_city][i]), BETA)
                    total_prob += select_citys_prob[i]
                except ZeroDivisionError as e:
                    print('Ant ID: {ID}, current city: {current}, target city: {target}'.format(ID=self.ID,
                                                                                                current=self.current_city,
                                                                                                target=i))
                    sys.exit(1)

        # 轮盘选择城市
        if total_prob > 0.0:
            # 产生一个随机概率,0.0-total_prob
            temp_prob = random.uniform(0.0, total_prob)
            for i in range(city_num):
                if self.open_table_city[i]:
                    # 轮次相减
                    temp_prob -= select_citys_prob[i]
                    if temp_prob < 0.0:
                        next_city = i
                        break

        if (next_city == -1):
            next_city = random.randint(1, city_num)
            while ((self.open_table_city[next_city]) == False):  # if==False,说明已经遍历过了
                next_city = random.randint(1, city_num)

        # 返回下一个城市序号
        return next_city

    # 计算路径总距离
    def __cal_total_distance(self):

        temp_distance = 0.0

        for i in range(1, city_num):
            start, end = self.path[i-1], self.path[i]
            temp_distance += distance_graph[start][end]

        # 回路
        start = self.path[0]
        temp_distance += distance_graph[start][end]
        self.total_distance = temp_distance

    # 移动操作
    def __move(self, next_city):

        self.path.append(next_city)
        self.open_table_city[next_city] = False
        self.total_distance += distance_graph[self.current_city][next_city]
        self.current_city = next_city
        self.move_count += 1

    # 搜索路径
    def search_path(self):

        # 初始化数据
        self.__clean_data()

        # 搜素路径,遍历完所有城市为止
        while self.move_count < city_num:
            # 移动到下一个城市
            next_city = self.__choice_next_city()
            self.__move(next_city)

        # 计算路径总长度
        self.__cal_total_distance()
class VRP(object):
    def __init__(self,n=city_num):
        self.n = n
        # 计算城市之间的距离
        for i in range(city_num):
            for j in range(city_num):
                temp_distance = pow((distance_x[i] - distance_x[j]), 2) + pow((distance_y[i] - distance_y[j]), 2)
                temp_distance = pow(temp_distance, 0.5)
                #distance_graph[i][j] = float(int(temp_distance + 0.5))
                distance_graph[i][j] = temp_distance
        self.ants = [Ant(ID) for ID in range(ant_num)]  # 初始蚁群
        self.best_ant = Ant(-1)  # 初始最优解
        self.best_ant.total_distance = 1 << 31  # 初始最大距离
        self.iter = 1  # 初始化迭代次数

    # 开始搜索
    def search_path(self):
        while self.iter < 2000:
            # 遍历每一只蚂蚁
            for ant in self.ants:
                # 搜索一条路径
                ant.search_path()
                # 与当前最优蚂蚁比较
                if ant.total_distance < self.best_ant.total_distance:
                    # 更新最优解
                    self.best_ant = copy.deepcopy(ant)
            # 更新信息素
            self.__update_pheromone_gragh()
            self.iter += 1

    # 更新信息素
    def __update_pheromone_gragh(self):

        # 获取每只蚂蚁在其路径上留下的信息素
        temp_pheromone = [[0.0 for col in range(city_num)] for raw in range(city_num)]
        for ant in self.ants:
            for i in range(1, city_num):
                start, end = ant.path[i - 1], ant.path[i]
                # 在路径上的每两个相邻城市间留下信息素,与路径总距离反比
                temp_pheromone[start][end] += Q / ant.total_distance
                temp_pheromone[end][start] = temp_pheromone[start][end]

        # 更新所有城市之间的信息素,旧信息素衰减加上新迭代信息素
        for i in range(city_num):
            for j in range(city_num):
                pheromone_graph[i][j] = pheromone_graph[i][j] * (1-RHO) + RHO * temp_pheromone[i][j]
if __name__ == '__main__':
    vrp = VRP()
    vrp.search_path()
    best_path = vrp.best_ant.path  #得出的最优TSP路径
    print('最优路径:', best_path)
    top_height = 8      #最大载重量
    top_distance = 50 #最远行驶距离
    final_way = [0] #记录最终路径
    now_height = 0 #当前车的当前载重量
    now_distance = 0 #当前车的当前行驶的距离
    k = 1 #记录用几辆车
    all_distance = 0 #所有车合起来行驶的距离
    for i in range(1,21):  #分解TSP路径为VRP路径
        if(now_height==0): #判断是否是从头开始
            now_height = now_height + need[best_path[i]]
            now_distance = distance_graph[0][best_path[i]]
            final_way.append(best_path[i])
        # 可以到达下一地点并且回来
        elif(now_height+need[best_path[i]] <=top_height and
             (now_distance + distance_graph[best_path[i-1]][best_path[i]] + distance_graph[0][best_path[i]]) <= top_distance):
            final_way.append(best_path[i])
            now_height = now_height + need[best_path[i]]
            now_distance = now_distance + distance_graph[best_path[i-1]][best_path[i]]

        else:
        #让上一辆车返回,并开始新的一辆
            final_way.append(0)
            now_distance = now_distance + distance_graph[0][best_path[i-1]]
            print('第{}辆车的路径为{},载重{},行驶距离{}'.format(k,final_way,now_height,now_distance))
            all_distance = all_distance + now_distance
            k += 1
            now_height = need[best_path[i]]
            now_distance = distance_graph[0][best_path[i]]
            final_way = [0,best_path[i]]
        if (i == 20):
            final_way.append(0)
            now_distance = now_distance + distance_graph[0][best_path[i]]
            print('第{}辆车的路径为{},载重{},行驶距离{}'.format(k, final_way, now_height, now_distance))
            all_distance = all_distance + now_distance
    print(all_distance)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值