基于python语言,实现经典禁忌搜索(TS)+模拟退火(SA)对车辆路径规划问题(CVRP)进行求解, 优化代码结构,改进Split函数
往期优质资源
-
CVRP系列
-
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
MDVRP系列
-
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
VRPTW系列
-
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
HVRP系列
-
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
MDHFVRPTW系列
-
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
1. 适用场景
- 求解CVRP
- 车辆类型单一
- 车辆容量不小于需求节点最大需求
- 单一车辆基地
2. 改进效果对比
这里做了简单的参数敏感性分析,量子粒子群算法的参数较少,只有一个 创新参数 alpha,参数调整范围为:[0.1,0.95],步长为0.05其他参数:最大迭代次数为300,车辆容量为80。
2.1 实验结果汇总
(1)SA
(2)TS
3. 求解结果
3.1 SA
(1)收敛曲线
(2)车辆路径
3.2 TS
(1)收敛曲线
(2)车辆路径
4. 部分代码
(1)数据结构
# 数据结构:解
class Sol():
def __init__(self):
self.node_no_seq=None # 解的编码
self.obj=None # 目标函数
self.route_list=None # 解的解码
self.route_distance = None # 车辆路径的长度集合
# 数据结构:网络节点
class Node():
def __init__(self):
self.id=0 # 节点id
self.x_coord=0 # 节点平面横坐标
self.y_coord=0 # 节点平面纵坐标
self.demand=0 # 节点需求
class Model():
def __init__(self):
self.best_sol=None # 全局最优解
self.node_id_list=[] # 需求节点集合
self.sol_list=[] # 解的集合
self.demand_dict={} #需求节点映射id集合
self.distance_matrix = {}
self.depot=None # 车场节点
self.number_of_demands=0 # 需求节点数量
self.vehicle_cap=0 # 车辆最大容量
self.Cr=0.5 # 差分交叉概率
self.F=0.5 # 差分变异概率
self.popsize=0
(2)距离矩阵
# 计算距离矩阵
def calDistanceMatrix(model):
for i in model.node_id_list:
for j in model.node_id_list:
d=math.sqrt((model.demand_dict[i].x_coord-model.demand_dict[j].x_coord)**2+
(model.demand_dict[i].y_coord-model.demand_dict[j].y_coord)**2)
model.distance_matrix[i,j]=d
dist = math.sqrt((model.demand_dict[i].x_coord - model.depot.x_coord) ** 2
+ (model.demand_dict[i].y_coord - model.depot.y_coord) ** 2)
model.distance_matrix[i, model.depot.id] = dist
model.distance_matrix[model.depot.id, i] = dist
(3)路径提取
def extractRoutes(node_no_seq,P,depot_id):
route_list = []
j = len(node_no_seq)
while True:
i = P[node_no_seq[j-1]]
route = [depot_id]
route.extend(node_no_seq[k] for k in range(i+1, j))
route.append(depot_id)
route_list.append(route)
j = i+1
if i == -1:
break
return route_list
(4)邻域搜索
# 定义邻域算子
def createActions(n):
action_list=[]
nswap=n//2
#第一种算子(Swap):前半段与后半段对应位置一对一交换
for i in range(nswap):
action_list.append([1,i,i+nswap])
#第二中算子(DSwap):前半段与后半段对应位置二对二交换
for i in range(0,nswap,2):
action_list.append([2,i,i+nswap])
#第三种算子(Reverse):指定长度的序列反序
for i in range(0,n,4):
action_list.append([3,i,i+3])
return action_list
# 执行邻域搜索
def doAction(node_no_seq,action):
node_no_seq=copy.deepcopy(node_no_seq)
if action[0]==1:
index_1=action[1]
index_2=action[2]
temporary=node_no_seq[index_1]
node_no_seq[index_1]=node_no_seq[index_2]
node_no_seq[index_2]=temporary
return node_no_seq
elif action[0]==2:
index_1 = action[1]
index_2 = action[2]
temporary=[node_no_seq[index_1],node_no_seq[index_1+1]]
node_no_seq[index_1]=node_no_seq[index_2]
node_no_seq[index_1+1]=node_no_seq[index_2+1]
node_no_seq[index_2]=temporary[0]
node_no_seq[index_2+1]=temporary[1]
return node_no_seq
elif action[0]==3:
index_1=action[1]
index_2=action[2]
node_no_seq[index_1:index_2+1]=list(reversed(node_no_seq[index_1:index_2+1]))
return node_no_seq
5. 完整代码
如有错误,欢迎交流。
私信,有偿
参考
- A simple and effective evolutionary algorithm for the vehicle routing problem