【进阶二】Python实现(MD)VRPTW常见求解算法——自适应大邻域搜索算法(ALNS)
基于python语言,实现经典自适应大邻域搜索算法(ALNS)对(多车场)带有时间窗的车辆路径规划问题( (MD) VRPTW )进行求解。
目录
- 往期优质资源
- 1. 适用场景
- 2. 求解效果
- 3. 代码分析
- 4. 数据格式
- 5. 分步实现
- 6. 完整代码
往期优质资源
- python实现6种智能算法求解CVRP问题
- python实现7种智能算法求解MDVRP问题
- python实现7种智能算法求解MDVRPTW问题
- Python版MDHFVRPTW问题智能求解算法代码【TS算法】
- Python版MDHFVRPTW问题智能求解算法代码【SA算法】
- Python版MDHFVRPTW问题智能求解算法代码【GA算法】
- Python版MDHFVRPTW问题智能求解算法代码【DPSO算法】
- Python版MDHFVRPTW问题智能求解算法代码【DE算法】
- Python版MDHFVRPTW问题智能求解算法代码【ACO算法】
- Python版HVRP问题智能求解算法代码【GA算法】
- Python版HVRP问题智能求解算法代码【DPSO算法】
1. 适用场景
- 求解MDVRPTW或VRPTW
- 车辆类型单一
- 车辆容量不小于需求节点最大需求
- 车辆路径长度或运行时间无限制
- 需求节点服务成本满足三角不等式
- 节点时间窗至少满足车辆路径只包含一个需求节点的情况
- 多车辆基地或单一
- 各车场车辆总数满足实际需求
2. 求解效果
(1)收敛曲线
(2)车辆路径
3. 代码分析
应用ALNS算法求解MDVRPTW时保留了已有代码的架构与思路,为能够求解带有时间窗的(多车场)车辆路径规划问题,这里参考既有文献对路径分割算法进行了改进("splitRoutes"函数),在分割车辆路径时不仅考虑了车辆容量限制,还考虑了节点的时间窗约束,以此使得分割后的路径可行。在此改进下继承了大量原有代码,降低了代码改进量。
4. 数据格式
以csv文件储存数据,其中demand.csv文件记录需求节点数据,共包含需求节点id,需求节点横坐标,需求节点纵坐标,需求量;depot.csv文件记录车场节点数据,共包含车场id,车场横坐标,车场纵坐标,车队数量。需要注意的是:需求节点id应为整数,车场节点id任意,但不可与需求节点id重复。 可参考github主页相关文件。
5. 分步实现
(1)数据结构
定义Sol()类,Node()类,Model()类,其属性如下表:
- Sol()类,表示一个可行解
属性 | 描述 |
---|---|
obj | 优化目标值 |
node_id_list | 需求节点id有序排列集合 |
cost_of_distance | 距离成本 |
cost_of_time | 时间成本 |
action_id | 解所对应的算子id,用于禁用算子 |
route_list | 车辆路径集合,对应MDVRPTW的解 |
timetable_list | 车辆节点访问时间集合,对应MDVRPTW的解 |
- Node()类,表示一个网络节点
属性 | 描述 |
---|---|
id | 物理节点id,需唯一 |
x_coord | 物理节点x坐标 |
y_coord | 物理节点y坐标 |
demand | 物理节点需求 |
depot_capacity | 车辆基地车队规模 |
start_time | 最早开始服务(被服务)时间 |
end_time | 最晚结束服务(被服务)时间 |
service_time | 需求节点服务时间 |
- Model()类,存储算法参数
属性 | 描述 |
---|---|
best_sol | 全局最优解,值类型为Sol() |
demand_dict | 需求节点集合(字典),值类型为Node() |
depot_dict | 车场节点集合(字典),值类型为Node() |
depot_id_list | 车场节点id集合 |
demand_id_list | 需求节点id集合 |
distance_matrix | 节点距离矩阵 |
time_matrix | 节点旅行时间矩阵 |
number_of_demands | 需求节点数量 |
opt_type | 优化目标类型,0:最小旅行距离,1:最小时间成本 |
vehicle_cap | 车辆容量 |
vehicle_speed | 车辆行驶速度,用于计算旅行时间 |
rand_d_max | 随机破坏程度上限 |
rand_d_min | 随机破坏程度下限 |
worst_d_max | 最坏破坏程度上限 |
worst_d_min | 最坏破坏程度下限 |
regret_n | 次优位置个数 |
r1 | 算子奖励1 |
r2 | 算子奖励2 |
r3 | 算子奖励3 |
rho | 算子权重衰减系数 |
d_weight | 破坏算子权重 |
d_select | 破坏算子被选中次数/每轮 |
d_score | 破坏算子被奖励得分/每轮 |
d_history_select | 破坏算子历史共计被选中次数 |
d_history_score | 破坏算子历史共计被奖励得分 |
r_weight | 修复算子权重 |
r_select | 修复算子被选中次数/每轮 |
r_score | 修复算子被奖励得分/每轮 |
r_history_select | 修复算子历史共计被选中次数 |
r_history_score | 修复算子历史共计被奖励得分 |
(2)文件读取
def readCSVFile(demand_file,depot_file,model):with open(demand_file,'r') as f:demand_reader=csv.DictReader(f)for row in demand_reader:node = Node()node.id = int(row['id'])node.x_coord = float(row['x_coord'])node.y_coord = float(row['y_coord'])node.demand = float(row['demand'])node.start_time=float(row['start_time'])node.end_time=float(row['end_time'])node.service_time=float(row['service_time'])model.demand_dict[node.id] = nodemodel.demand_id_list.append(node.id)model.number_of_demands=len(model.demand_id_list)with open(depot_file, 'r') as f:depot_reader = csv.DictReader(f)for row in depot_reader:node = Node()node.id = row['id']node.x_coord = float(row['x_coord'])node.y_coord = float(row['y_coord'])node.depot_capacity = float(row['capacity'])node.start_time=float(row['start_time'])node.end_time=float(row['end_time'])model.depot_dict[node.id] = nodemodel.depot_id_list.append(node.id)
(3)计算距离&时间矩阵
def calDistanceTimeMatrix(model):for i in range(len(model.demand_id_list)):from_node_id = model.demand_id_list[i]for j in range(i + 1, len(model.demand_id_list)):to_node_id = model.demand_id_list[j]dist = math.sqrt((model.demand_dict[from_node_id].x_coord - model.demand_dict[to_node_id].x_coord) ** 2+ (model.demand_dict[from_node_id].y_coord - model.demand_dict[to_node_id].y_coord) ** 2)model.distance_matrix[from_node_id, to_node_id] = distmodel.distance_matrix[to_node_id, from_node_id] = distmodel.time_matrix[from_node_id,to_node_id] = math.ceil(dist/model.vehicle_speed)model.time_matrix[to_node_id,from_node_id] = math.ceil(dist/model.vehicle_speed)for _, depot in model.depot_dict.items():dist = math.sqrt((model.demand_dict[from_node_id].x_coord - depot.x_coord) ** 2+ (model.demand_dict[from_node_id].y_coord - depot.y_coord) ** 2)model.distance_matrix[from_node_id, depot.id] = distmodel.distance_matrix[depot.id, from_node_id] = distmodel.time_matrix[from_node_id,depot.id] = math.ceil(dist/model.vehicle_speed)model.time_matrix[depot.id,from_node_id] = math.ceil(dist/model.vehicle_speed)
(4)目标值计算
适应度计算依赖" splitRoutes "函数对有序节点序列行解分割得到车辆行驶路线,同时在得到各车辆形式路线后在满足车场车队规模条件下分配最近车场,之后调用 " calTravelCost "函数确定车辆访问各路径节点的到达和离开时间点,并计算旅行距离成本和旅行时间成本。
def selectDepot(route,depot_dict,model):min_in_out_distance=float('inf')index=Nonefor _,depot in depot_dict.items():if depot.depot_capacity>0:in_out_distance=model.distance_matrix[depot.id,route[0]]+model.distance_matrix[route[-1],depot.id]if in_out_distance<min_in_out_distance:index=depot.idmin_in_out_distance=in_out_distanceif index is None:print("there is no vehicle to dispatch")sys.exit(0)route.insert(0,index)route.append(index)depot_dict[index].depot_capacity=depot_dict[index].depot_capacity-1return route,depot_dictdef calTravelCost(route_list,model):timetable_list=[]cost_of_distance=0cost_of_time=0for route in route_list:timetable=[]for i in range(len(route)):if i == 0:depot_id=route[i]next_node_id=route[i+1]travel_time=model.time_matrix[depot_id,next_node_id]departure=max(0,model.demand_dict[next_node_id].start_time-travel_time)timetable.append((departure,departure))elif 1<= i <= len(route)-2:last_node_id=route[i-1]current_node_id=route[i]current_node = model.demand_dict[current_node_id]travel_time=model.time_matrix[last_node_id,current_node_id]arrival=max(timetable[-1][1]+travel_time,current_node.start_time)departure=arrival+current_node.service_timetimetable.append((arrival,departure))cost_of_distance += model.distance_matrix[last_node_id, current_node_id]cost_of_time += model.time_matrix[last_node_id, current_node_id]+ current_node.service_time\+ max(current_node.start_time - timetable[-1][1] + travel_time, 0)else:last_node_id = route[i - 1]depot_id=route[i]travel_time = model.time_matrix[last_node_id,depot_id]departure = timetable[-1][1]+travel_timetimetable.append((departure,departure))cost_of_distance +=model.distance_matrix[last_node_id,depot_id]cost_of_time+=model.time_matrix[last_node_id,depot_id]timetable_list.append(timetable)return timetable_list,cost_of_time,cost_of_distancedef extractRoutes(node_id_list,Pred,model):depot_dict=copy.deepcopy(model.depot_dict)route_list = []route = []label = Pred[node_id_list[0]]for node_id in node_id_list:if Pred[node_id] == label:route.append(node_id)else:route, depot_dict=selectDepot(route,depot_dict,model)route_list.append(route)route = [node_id]label = Pred[node_id]route, depot_dict = selectDepot(route, depot_dict, model)route_list.append(route)return route_listdef splitRoutes(node_id_list,model):depot=model.depot_id_list[0]V={id:float('inf') for id in model.demand_id_list}V[depot]=0Pred={id:depot for id in model.demand_id_list}for i in range(len(node_id_list)):n_1=node_id_list[i]demand=0departure=0j=icost=0while True:n_2 = node_id_list[j]demand = demand + model.demand_dict[n_2].demandif n_1 == n_2:arrival= max(model.demand_dict[n_2].start_time,model.depot_dict[depot].start_time+model.time_matrix[depot,n_2])departure=arrival+model.demand_dict[n_2].service_time+model.time_matrix[n_2,depot]if model.opt_type == 0:cost=model.distance_matrix[depot,n_2]*2else:cost=model.time_matrix[depot,n_2]*2else:n_3=node_id_list[j-1]arrival= max(departure-model.time_matrix[n_3,depot]+model.time_matrix[n_3,n_2],model.demand_dict[n_2].start_time)departure=arrival+model.demand_dict[n_2].service_time+model.time_matrix[n_2,depot]if model.opt_type == 0:cost=cost-model.distance_matrix[n_3,depot]+model.distance_matrix[n_3,n_2]+model.distance_matrix[n_2,depot]else:cost=cost-model.time_matrix[n_3,depot]+model.time_matrix[n_3,n_2]\+model.demand_dict[n_2].start_time-departure-model.time_matrix[n_3,depot]+model.time_matrix[n_3,n_2]\+model.time_matrix[n_2,depot]if demand<=model.vehicle_cap and departure-model.time_matrix[n_2,depot] <= model.demand_dict[n_2].end_time:if departure <= model.depot_dict[depot].end_time:n_4=node_id_list[i-1] if i-1>=0 else depotif V[n_4]+cost <= V[n_2]:V[n_2]=V[n_4]+costPred[n_2]=i-1j=j+1else:breakif j==len(node_id_list):breakroute_list= extractRoutes(node_id_list,Pred,model)return len(route_list),route_listdef calObj(sol,model):node_id_list=copy.deepcopy(sol.node_id_list)num_vehicle, sol.route_list = splitRoutes(node_id_list, model)# travel costsol.timetable_list,sol.cost_of_time,sol.cost_of_distance =calTravelCost(sol.route_list,model)if model.opt_type == 0:sol.obj=sol.cost_of_distanceelse:sol.obj=sol.cost_of_time
(5)初始解
def genInitialSol(node_id_list):node_id_list=copy.deepcopy(node_id_list)random.seed(0)random.shuffle(node_id_list)return node_id_list
(6)定义destroy算子(破坏算子)
def createRandomDestory(model):d=random.uniform(model.rand_d_min,model.rand_d_max)reomve_list=random.sample(range(len(model.demand_id_list)),int(d*len(model.demand_id_list)))return reomve_listdef createWorseDestory(model,sol):deta_f=[]for node_id in sol.node_id_list:sol_=copy.deepcopy(sol)sol_.node_id_list.remove(node_id)calObj(sol_,model)deta_f.append(sol.obj-sol_.obj)sorted_id = sorted(range(len(deta_f)), key=lambda k: deta_f[k], reverse=True)d=random.randint(model.worst_d_min,model.worst_d_max)remove_list=sorted_id[:d]return remove_list
(7)定义repair算子(修复算子)
def createRandomRepair(remove_list,model,sol):unassigned_nodes_id=[]assigned_nodes_id = []# remove node from current solutionfor i in range(len(model.demand_id_list)):if i in remove_list:unassigned_nodes_id.append(sol.node_id_list[i])else:assigned_nodes_id.append(sol.node_id_list[i])# insertfor node_id in unassigned_nodes_id:index=random.randint(0,len(assigned_nodes_id)-1)assigned_nodes_id.insert(index,node_id)new_sol=Sol()new_sol.node_id_list=copy.deepcopy(assigned_nodes_id)calObj(new_sol,model)return new_soldef findGreedyInsert(unassigned_nodes_id,assigned_nodes_id,model):best_insert_node_id=Nonebest_insert_index = Nonebest_insert_cost = float('inf')sol_1=Sol()sol_1.node_id_list=assigned_nodes_idcalObj(sol_1,model)for node_id in unassigned_nodes_id:for i in range(len(assigned_nodes_id)):sol_2=Sol()sol_2.node_id_list=copy.deepcopy(assigned_nodes_id)sol_2.node_id_list.insert(i, node_id)calObj(sol_2, model)deta_f = sol_2.obj -sol_1.objif deta_f<best_insert_cost:best_insert_index=ibest_insert_node_id=node_idbest_insert_cost=deta_freturn best_insert_node_id,best_insert_indexdef createGreedyRepair(remove_list,model,sol):unassigned_nodes_id = []assigned_nodes_id = []# remove node from current solutionfor i in range(len(model.demand_id_list)):if i in remove_list:unassigned_nodes_id.append(sol.node_id_list[i])else:assigned_nodes_id.append(sol.node_id_list[i])#insertwhile len(unassigned_nodes_id)>0:insert_node_id,insert_index=findGreedyInsert(unassigned_nodes_id,assigned_nodes_id,model)assigned_nodes_id.insert(insert_index,insert_node_id)unassigned_nodes_id.remove(insert_node_id)new_sol=Sol()new_sol.node_id_list=copy.deepcopy(assigned_nodes_id)calObj(new_sol,model)return new_soldef findRegretInsert(unassigned_nodes_id,assigned_nodes_id,model):opt_insert_node_id = Noneopt_insert_index = Noneopt_insert_cost = -float('inf')sol_=Sol()for node_id in unassigned_nodes_id:n_insert_cost=np.zeros((len(assigned_nodes_id),3))for i in range(len(assigned_nodes_id)):sol_.node_id_list=copy.deepcopy(assigned_nodes_id)sol_.node_id_list.insert(i,node_id)calObj(sol_,model)n_insert_cost[i,0]=node_idn_insert_cost[i,1]=in_insert_cost[i,2]=sol_.objn_insert_cost= n_insert_cost[n_insert_cost[:, 2].argsort()]deta_f=0for i in range(1,model.regret_n):deta_f=deta_f+n_insert_cost[i,2]-n_insert_cost[0,2]if deta_f>opt_insert_cost:opt_insert_node_id = int(n_insert_cost[0, 0])opt_insert_index=int(n_insert_cost[0,1])opt_insert_cost=deta_freturn opt_insert_node_id,opt_insert_indexdef createRegretRepair(remove_list,model,sol):unassigned_nodes_id = []assigned_nodes_id = []# remove node from current solutionfor i in range(len(model.demand_id_list)):if i in remove_list:unassigned_nodes_id.append(sol.node_id_list[i])else:assigned_nodes_id.append(sol.node_id_list[i])# insertwhile len(unassigned_nodes_id)>0:insert_node_id,insert_index=findRegretInsert(unassigned_nodes_id,assigned_nodes_id,model)assigned_nodes_id.insert(insert_index,insert_node_id)unassigned_nodes_id.remove(insert_node_id)new_sol = Sol()new_sol.node_id_list = copy.deepcopy(assigned_nodes_id)calObj(new_sol, model)return new_sol
(8)随机选择算子
def selectDestoryRepair(model):d_weight=model.d_weightd_cumsumprob = (d_weight / sum(d_weight)).cumsum()d_cumsumprob -= np.random.rand()destory_id= list(d_cumsumprob > 0).index(True)r_weight=model.r_weightr_cumsumprob = (r_weight / sum(r_weight)).cumsum()r_cumsumprob -= np.random.rand()repair_id = list(r_cumsumprob > 0).index(True)return destory_id,repair_id
(9)执行destory算子
def doDestory(destory_id,model,sol):if destory_id==0:reomve_list=createRandomDestory(model)else:reomve_list=createWorseDestory(model,sol)return reomve_list
(10)执行repair算子
def doRepair(repair_id,reomve_list,model,sol):if repair_id==0:new_sol=createRandomRepair(reomve_list,model,sol)elif repair_id==1:new_sol=createGreedyRepair(reomve_list,model,sol)else:new_sol=createRegretRepair(reomve_list,model,sol)return new_sol
(11)重置算子得分
def resetScore(model):model.d_select = np.zeros(2)model.d_score = np.zeros(2)model.r_select = np.zeros(3)model.r_score = np.zeros(3)
(12)更新算子权重
def updateWeight(model):for i in range(model.d_weight.shape[0]):if model.d_select[i]>0:model.d_weight[i]=model.d_weight[i]*(1-model.rho)+model.rho*model.d_score[i]/model.d_select[i]else:model.d_weight[i] = model.d_weight[i] * (1 - model.rho)for i in range(model.r_weight.shape[0]):if model.r_select[i]>0:model.r_weight[i]=model.r_weight[i]*(1-model.rho)+model.rho*model.r_score[i]/model.r_select[i]else:model.r_weight[i] = model.r_weight[i] * (1 - model.rho)model.d_history_select = model.d_history_select + model.d_selectmodel.d_history_score = model.d_history_score + model.d_scoremodel.r_history_select = model.r_history_select + model.r_selectmodel.r_history_score = model.r_history_score + model.r_score
(13)绘制收敛曲线
def plotObj(obj_list):plt.rcParams['font.sans-serif'] = ['SimHei'] #show chineseplt.rcParams['axes.unicode_minus'] = False # Show minus signplt.plot(np.arange(1,len(obj_list)+1),obj_list)plt.xlabel('Iterations')plt.ylabel('Obj Value')plt.grid()plt.xlim(1,len(obj_list)+1)plt.show()
(14)绘制车辆路线
def plotRoutes(model):for route in model.best_sol.route_list:x_coord=[model.depot_dict[route[0]].x_coord]y_coord=[model.depot_dict[route[0]].y_coord]for node_id in route[1:-1]:x_coord.append(model.demand_dict[node_id].x_coord)y_coord.append(model.demand_dict[node_id].y_coord)x_coord.append(model.depot_dict[route[-1]].x_coord)y_coord.append(model.depot_dict[route[-1]].y_coord)plt.grid()if route[0]=='d1':plt.plot(x_coord,y_coord,marker='o',color='black',linewidth=0.5,markersize=5)elif route[0]=='d2':plt.plot(x_coord,y_coord,marker='o',color='orange',linewidth=0.5,markersize=5)else:plt.plot(x_coord,y_coord,marker='o',color='b',linewidth=0.5,markersize=5)plt.xlabel('x_coord')plt.ylabel('y_coord')plt.show()
(15)输出结果
def outPut(model):work=xlsxwriter.Workbook('result.xlsx')worksheet=work.add_worksheet()worksheet.write(0, 0, 'cost_of_time')worksheet.write(0, 1, 'cost_of_distance')worksheet.write(0, 2, 'opt_type')worksheet.write(0, 3, 'obj')worksheet.write(1,0,model.best_sol.cost_of_time)worksheet.write(1,1,model.best_sol.cost_of_distance)worksheet.write(1,2,model.opt_type)worksheet.write(1,3,model.best_sol.obj)worksheet.write(2,0,'vehicleID')worksheet.write(2,1,'route')worksheet.write(2,2,'timetable')for row,route in enumerate(model.best_sol.route_list):worksheet.write(row+3,0,'v'+str(row+1))r=[str(i)for i in route]worksheet.write(row+3,1, '-'.join(r))r=[str(i)for i in model.best_sol.timetable_list[row]]worksheet.write(row+3,2, '-'.join(r))work.close()
(16)主函数
def run(demand_file,depot_file,rand_d_max,rand_d_min,worst_d_min,worst_d_max,regret_n,r1,r2,r3,rho,phi,epochs,pu,v_cap,v_speed,opt_type):""":param demand_file: demand file path:param depot_file: depot file path:param rand_d_max: max degree of random destruction:param rand_d_min: min degree of random destruction:param worst_d_max: max degree of worst destruction:param worst_d_min: min degree of worst destruction:param regret_n: n next cheapest insertions:param r1: score if the new solution is the best one found so far.:param r2: score if the new solution improves the current solution.:param r3: score if the new solution does not improve the current solution, but is accepted.:param rho: reaction factor of action weight:param phi: the reduction factor of threshold:param epochs: Iterations:param pu: the frequency of weight adjustment:param v_cap: Vehicle capacity:param opt_type: Optimization type:0:Minimize the number of vehicles,1:Minimize travel distance:return:"""model=Model()model.rand_d_max=rand_d_maxmodel.rand_d_min=rand_d_minmodel.worst_d_min=worst_d_minmodel.worst_d_max=worst_d_maxmodel.regret_n=regret_nmodel.r1=r1model.r2=r2model.r3=r3model.rho=rhomodel.vehicle_cap=v_capmodel.opt_type=opt_typemodel.vehicle_speed=v_speedreadCSVFile(demand_file,depot_file, model)calDistanceTimeMatrix(model)history_best_obj = []sol = Sol()sol.node_id_list = genInitialSol(model.demand_id_list)calObj(sol, model)model.best_sol = copy.deepcopy(sol)history_best_obj.append(sol.obj)for ep in range(epochs):T=sol.obj*0.2resetScore(model)for k in range(pu):destory_id,repair_id=selectDestoryRepair(model)model.d_select[destory_id]+=1model.r_select[repair_id]+=1reomve_list=doDestory(destory_id,model,sol)new_sol=doRepair(repair_id,reomve_list,model,sol)if new_sol.obj<sol.obj:sol=copy.deepcopy(new_sol)if new_sol.obj<model.best_sol.obj:model.best_sol=copy.deepcopy(new_sol)model.d_score[destory_id]+=model.r1model.r_score[repair_id]+=model.r1else:model.d_score[destory_id]+=model.r2model.r_score[repair_id]+=model.r2elif new_sol.obj-sol.obj<T:sol=copy.deepcopy(new_sol)model.d_score[destory_id] += model.r3model.r_score[repair_id] += model.r3T=T*phiprint("%s/%s:%s/%s, best obj: %s" % (ep,epochs,k,pu, model.best_sol.obj))history_best_obj.append(model.best_sol.obj)updateWeight(model)plotObj(history_best_obj)plotRoutes(model)outPut(model)print("random destory weight is {:.3f}\tselect is {}\tscore is {:.3f}".format(model.d_weight[0],model.d_history_select[0],model.d_history_score[0]))print("worse destory weight is {:.3f}\tselect is {}\tscore is {:.3f} ".format(model.d_weight[1],model.d_history_select[1],model.d_history_score[1]))print("random repair weight is {:.3f}\tselect is {}\tscore is {:.3f}".format(model.r_weight[0],model.r_history_select[0],model.r_history_score[0]))print("greedy repair weight is {:.3f}\tselect is {}\tscore is {:.3f}".format(model.r_weight[1],model.r_history_select[1],model.r_history_score[1]))print("regret repair weight is {:.3f}\tselect is {}\tscore is {:.3f}".format(model.r_weight[2],model.r_history_select[2],model.r_history_score[2]))
6. 完整代码
代码和数据文件可获取:
https://download.csdn.net/download/python_n/56114085
【进阶二】Python实现(MD)VRPTW常见求解算法——自适应大邻域搜索算法(ALNS)相关推荐
- 【进阶四】Python实现(MD)HVRP常见求解算法——蚁群算法(ACO)
蚁群算法+Split 求解异构车辆路径规划问题 目录 信息传递 1. 适用场景 2. 求解效果 3. 代码分析 4. 数据格式 5. 分步实现 6. 完整代码 参考 信息传递 python实现6种智能 ...
- 【进阶四】Python实现(MD)HVRP常见求解算法——差分进化算法(DE)
差分进化算法+Split 求解异构车辆路径规划问题 碧海蓝天 吹吹风 目录 信息传递 1. 适用场景 2. 求解效果 3. 代码分析 4. 数据格式 5. 分步实现 6. 完整代码 参考 信息传递 p ...
- 【进阶二】Python实现VRPTW常见求解算法——差分进化算法(DE)
基于python语言,实现经典差分进化算法(DE)对带有时间窗的车辆路径规划问题( VRPTW )进行求解. 目录 往期优质资源 1. 适用场景 2. 求解效果 3. 代码分析 4. 数据格式 5. ...
- TSP问题解析篇之自适应大邻域搜索(ALNS)算法深度通读(附python代码)
01 概念科普篇 关于neighborhood serach,这里有好多种衍生和变种出来的胡里花俏的算法.大家在上网搜索的过程中可能看到什么Large Neighborhood Serach,也可能看 ...
- 【进阶一】Python实现MDCVRP常见求解算法——蚁群算法(ACO)
基于python语言,实现蚁群算法(ACO)对多车场车辆路径规划问题(MDCVRP)进行求解. 目录 往期优质资源 1. 适用场景 2. 求解效果 3. 代码分析 4. 数据格式 5. 分步实现 6. ...
- 【进阶一】Python实现MDCVRP常见求解算法——差分进化算法(DE)
基于python语言,实现差分进化算法(DE)对多车场车辆路径规划问题(MDCVRP)进行求解. 目录 往期优质资源 1. 适用场景 2. 求解效果 3. 代码分析 4. 数据格式 5. 分步实现 6 ...
- 【改进篇】Python实现VRP常见求解算法——禁忌搜索算法(TS)
基于python语言,实现经典禁忌搜索算法(TS)对车辆路径规划问题(CVRP)进行求解, 优化代码结构,改进Split函数 目录 往期优质资源 1. 适用场景 2. 改进效果对比 3. 求解结果 4 ...
- Python实现VRP常见求解算法——蚁群算法(ACO)
基于python语言,实现经典蚁群算法(ACO)对车辆路径规划问题(CVRP)进行求解. 目录 优质资源 1. 适用场景 2. 求解效果 3. 问题分析 4. 数据格式 5. 分步实现 6. 完整代码 ...
- Python实现VRP常见求解算法——离散量子行为粒子群算法(DQPSO)
基于python语言,实现经典离散量子行为粒子群算法(DQPSO)对车辆路径规划问题(CVRP)进行求解. 目录 优质资源 1. 适用场景 2. 求解效果 3. 问题分析 4. 数据格式 5. 分步实 ...
最新文章
- Swift 代码调试-善用XCode工具(UI调试,五种断点,预览UIImage...)
- 大数据 清华 覃征_2021年清华(清华大学)大数据工程考研难度解析、考研经验分享...
- Node.js 环境下的 console.log 是同步执行的
- php特殊字符转化函数,PHP函数将Unicode转换成特殊字符?
- 《计算机应用》实践考核,《管理系统中计算机应用》实践性环节考核方案
- 346雷达有多少tr组件_有源相控阵的天线设计的核心:T/R组件
- Python 模块EasyGui
- 手摸手-100行代码实现一个功能完善的图片懒加载
- 用python建云盘_超简单!基于Python搭建个人“云盘”
- swift拖放的按钮如何在后台设置点击事件 www.cnblogs.com/foxting/p/SWIFT.html
- NB-IoT、eMTC与LoRa三大物联网技术相争,共存还是鏖战?
- 通俗讲解光线追踪原理,一文理清各类光线追踪
- 达叔926词汇pdf单词提取、保存
- 考研数学复习笔记——行列式1
- java+rabbitMQ实现一对一聊天
- ElasticsearchTemplate的详细使用,完成多条件查询、匹配度查询等
- 小程序高级电商前端第1周走进Web全栈工程师<二>
- QQ小程序百度网盘中的文件保存和下载
- 教育界杂志教育界杂志社教育界编辑部2022年第10期目录
- 计算机无法安装MUMU模拟器,如何安装网易MuMu模拟器 MuMu模拟器怎么用
热门文章
- 信息系统集成错题-IT技术
- 集合——离散数学part 1
- C++ pimp技巧
- 万用表测交流电压时测出的为有效值还是有效值?
- 这样直接运行Python命令,电脑等于“裸奔”
- 2020年会计职称考试教材《初级会计实务》内容修订
- java行业苏州和南京哪个好_苏州和南京哪个好哪个好玩 苏州和南京哪个打工好...
- 后盾php框架下载,后盾网HD框架下载_后盾网HD框架官方下载-太平洋下载中心
- Cambridge Pixel发布新产品雷达信号输出卡HPx-310
- 办公环境监测与智能控制软硬件全套解决方案