想和大神交朋友或想软件开发兼职接项目,请通过手机端搜小#程#序: "黄页小艺" 。
python
# %%
import folium
import random
import numpy as np
from tqdm import tqdm
from copy import deepcopy
from random import randint
import matplotlib.pyplot as plt
from geopy.distance import geodesic
#
# # %%
# pip install geopy
#
# # %%
# 需求点数量
demand_point_num=20
# 供应点数量
supply_point_num=3
# 冷库集合
cold_storage_num=5
# 节点总数
point_num=demand_point_num+supply_point_num+cold_storage_num
# 产品种类
product_type=3
# 车辆数
vehicle_num=8
# 需求矩阵
demand_matrix={}
for d in range(demand_point_num):
for p in range(product_type):
demand_matrix[d,p]=randint(10,100)
# 时间窗
time_window={}
for d in range(demand_point_num):
t1,t2,t=randint(0,100),randint(0,100),randint(1,10)
ET,LT=min(t1,t2),max(t1,t2)
time_window[d]=(ET,LT,t)
# 车辆的容量
vehicle_capacity={}
for v in range(vehicle_num):
vehicle_capacity[v]=[]
for p in range(product_type):
vehicle_capacity[v].append(randint(200,500))
# 车辆的承重和体积
vehicle_weight={}
vehicle_volume={}
for v in range(vehicle_num):
vehicle_weight[v]=randint(500,1000)
vehicle_volume[v]=randint(500,1000)
# 车辆的运行速度/最远行驶距离
vehicle_speed={}
vehicle_distance={}
for v in range(vehicle_num):
vehicle_speed[v]=randint(20,30)
vehicle_distance=randint(100000,200000)
# 车辆的固定/单位成本
vehicle_fix_cost={}
vehicle_unit_cost={}
for v in range(vehicle_num):
vehicle_fix_cost[v]=randint(1000,2000)
vehicle_unit_cost[v]=randint(5,10)/1e4
# 车辆早到/晚到的惩罚成本
a1,a2=10,10
# 产品的重量和体积
product_weight={}
product_volume={}
for p in range(product_type):
product_weight[p]=randint(1,5)
product_volume[p]=randint(1,5)
# 冷库的建设成本
cold_storage_fix_cost={}
for c in range(cold_storage_num):
cold_storage_fix_cost[c]=randint(1000000,3000000)
# 产品的重量/体积
product_weight={}
product_volume={}
for p in range(product_type):
product_weight[p]=randint(1,5)
product_volume[p]=randint(1,5)
# 节点坐标
node_point={}
for p in range(point_num):
lat=randint(30421,30425)/1000
lon=randint(120510,120530)/1000
node_point[p]=(lat,lon)
# 距离矩阵
distance_matrix={}
for p1 in range(point_num):
for p2 in range(point_num):
distance=geodesic(node_point[p1],node_point[p2]).m
distance_matrix[p1,p2]=distance
# %%
'''
整数转二进制
'''
def toBit(num,length):
bit=[]
for i in range(length-1,-1,-1):
bit.append(int(num/(supply_point_num+cold_storage_num)**i))
num-=bit[-1]*(supply_point_num+cold_storage_num)**i
return bit
'''
星雀个体
'''
class Nutcracker:
def __init__(self,individual):
self.individual=individual
self.result=self.decode()
self.fitness=self.get_fitness()
def decode(self):
result={}
bit=toBit(self.individual[0],vehicle_num)
demand=deepcopy(demand_matrix)
for i in self.individual[1]:
result[i]={}
serve_order=self.individual[2+i]
capacity=deepcopy(vehicle_capacity[i])
# 计算开始时间
cur_time=distance_matrix[0,bit[i]]/vehicle_speed[i]
cur_point=bit[i]
result[i][cur_point]={}
result[i][cur_point]['serve']={0:0,1:0,2:0}
result[i][cur_point]['time']={'t1':cur_time,'t2':cur_time,'t3':cur_time}
for j in serve_order:
jj=j+supply_point_num+cold_storage_num
# 车辆没有剩余容量
if sum(capacity)==0:
break
# 需求点没有剩余需求
if sum([demand[j,p] for p in range(product_type)])==0:
continue
result[i][j]={}
# 计算需求量
result[i][j]['serve']={}
for p in range(product_type):
min_num=min(demand[j,p],capacity[p])
demand[j,p]-=min_num
capacity[p]-=min_num
result[i][j]['serve'][p]=min_num
# 计算时间
arrive_time=cur_time+distance_matrix[cur_point,jj]/vehicle_speed[i]
satrt_serve_time=max(arrive_time,time_window[j][0])
departure_time=satrt_serve_time+time_window[j][2]
result[i][j]['time']={'t1':arrive_time,'t2':satrt_serve_time,'t3':departure_time}
cur_time=departure_time
cur_point=j
return result
def get_fitness(self):
fitness=0
self.result=self.decode()
# 冷库建设成本
bit=toBit(self.individual[0],vehicle_num)
cold_set=set()
for b in bit:
if b>=supply_point_num:
cold_set.add(b-supply_point_num)
fitness+=sum([cold_storage_fix_cost[c] for c in cold_set])/(5*365)
# 车辆运输成本
for i in self.result:
if self.result[i]:
fitness+=vehicle_fix_cost[i]
cur_point=bit[i]
for j in self.result[i]:
jj=j+supply_point_num+cold_storage_num
fitness+=vehicle_unit_cost[i]*distance_matrix[cur_point,jj]
cur_point=jj
# 需求延误成本
for j in range(demand_point_num):
min_arrive_time=1e8
max_arrive_time=0
for i in self.result:
if j in self.result[i]:
min_arrive_time=min(min_arrive_time,self.result[i][j]['time']['t1'])
max_arrive_time=max(max_arrive_time,self.result[i][j]['time']['t1'])
fitness+=a1*max(0,time_window[j][0]-min_arrive_time)
fitness+=a2*max(0,max_arrive_time-time_window[j][1])
self.fitness=1/fitness
return 1/fitness
'''
生成个体
'''
def gen_nutcracker():
num=randint(0,(supply_point_num+cold_storage_num)**vehicle_num-1)
vehicle_order=[i for i in range(vehicle_num)]
random.shuffle(vehicle_order)
serve_order=[]
for i in range(vehicle_num):
cur_order=[j for j in range(demand_point_num)]
random.shuffle(cur_order)
serve_order.append(cur_order)
individual=[num]+[vehicle_order]+serve_order
nutcracker=Nutcracker(individual)
return nutcracker
'''
生成种群
'''
def get_population(num):
population=[]
for i in range(num):
population.append(gen_nutcracker())
return population
'''
获取最优个体
'''
def get_best_nutcracker(population):
best_fitness=0
best_nutcracker=None
for nutcracker in population:
fitness=nutcracker.get_fitness()
if fitness>best_fitness:
best_fitness=fitness
best_nutcracker=nutcracker
return best_nutcracker
'''
觅食阶段
'''
def forage(nutcracker,population):
# 随机探索
if random.random()<exploring_probability:
individual=nutcracker.individual
individual[0]=randint(0,(supply_point_num+cold_storage_num)**vehicle_num-1)
nutcracker=Nutcracker(individual)
return nutcracker
# 最优探索
else:
best_nutcracker=get_best_nutcracker(population)
individual=nutcracker.individual
best_individual=best_nutcracker.individual
individual[0]=best_individual[0]
nutcracker=Nutcracker(individual)
return nutcracker
'''
储存阶段
'''
def store(nutcracker,best_population):
new_best_population=deepcopy(best_population)
new_best_population.append(nutcracker)
new_best_population=sorted(new_best_population, key=lambda x: x.get_fitness())
return new_best_population[1:]
'''
Levy飞行距离
'''
def levy_distance(nutcracker1,nutcracker2):
individual1=nutcracker1.individual
individual2=nutcracker2.individual
distance=abs(individual1[0]-individual2[0])/max(individual1[0],individual2[0])
for i in range(vehicle_num+1):
ii=i+1
sum1=0
for j in range(len(individual1[ii])):
sum1+=j*individual1[ii][j]
sum2=0
for j in range(len(individual2[ii])):
sum2+=j*individual2[ii][j]
distance+=abs(sum1-sum2)/max(sum1,sum2)
return distance
'''
缓存搜索阶段
'''
def search(nutcracker,best_population):
individual=nutcracker.individual
for cur_nutcracker in best_population:
if levy_distance(nutcracker,cur_nutcracker)>distance:
continue
cur_individual=cur_nutcracker.individual
new_individual=[]
for i in range(len(individual)):
if randint(0,1):
new_individual.append(individual[i])
else:
new_individual.append(cur_individual[i])
new_nutcracker=Nutcracker(new_individual)
if new_nutcracker.get_fitness()>nutcracker.get_fitness():
nutcracker=deepcopy(new_nutcracker)
return nutcracker
def swap(nutcracker):
individual=deepcopy(nutcracker.individual)
for i in range(len(individual[1])):
for j in range(i+1,len(individual[1])):
individual[1][i],individual[1][j]=individual[1][j],individual[1][i]
new_nutcracker=Nutcracker(individual)
if nutcracker.get_fitness()>new_nutcracker.get_fitness():
individual[1][i],individual[1][j]=individual[1][j],individual[1][i]
return Nutcracker(individual)
def new_search(nutcracker,best_population):
individual=nutcracker.individual
for cur_nutcracker in best_population:
if levy_distance(nutcracker,cur_nutcracker)>distance:
continue
cur_individual=cur_nutcracker.individual
new_individual=[]
for i in range(len(individual)):
if randint(0,1):
new_individual.append(individual[i])
else:
new_individual.append(cur_individual[i])
new_nutcracker=Nutcracker(new_individual)
if new_nutcracker.get_fitness()>nutcracker.get_fitness():
nutcracker=deepcopy(new_nutcracker)
return swap(nutcracker)
# %%
'''
绘制收敛图
'''
def plot_convergence(convergence_records):
num_curves = len(convergence_records)
for i in range(num_curves):
cur=convergence_records[i]
convergence_records[i]=[1/i for i in cur]
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w']
plt.figure(figsize=(20, 10))
for i, record in enumerate(convergence_records):
iterations = list(range(1, len(record) + 1))
plt.plot(iterations, record, marker='o', label=f'Curve {i+1}', color=colors[i % len(colors)])
plt.title('Convergence Plots')
plt.xlabel('Iteration')
plt.ylabel('Cost')
plt.legend()
plt.grid(False)
plt.show()
'''
绘制路线图
'''
def plot_locations(m,locations,color):
locations.append(locations[0])
folium.PolyLine(locations, color=color, weight=2.5, opacity=1).add_to(m)
for i, (lat, lon) in enumerate(locations):
color='blue'
for k in node_point:
point=(lat, lon)
if point==node_point[k]:
if k<supply_point_num:
color='red'
elif k<supply_point_num+cold_storage_num:
color='green'
folium.Marker([lat, lon], popup=f'Location {i+1}',icon=folium.Icon(color=color)).add_to(m)
return m
def plot_route(nutcracker):
m = folium.Map(location=node_point[0], zoom_start=13,tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_en&size=1&scale=1&style=8&x={x}&y={y}&z={z}', attr='高德-中英文对照')
color_list = [
'red', 'blue', 'green', 'purple', 'orange',
'darkred', 'lightred', 'beige', 'darkblue', 'darkgreen',
'cadetblue', 'darkpurple', 'white', 'pink', 'lightblue',
'lightgreen', 'gray', 'black', 'lightgray'
]
cnt=0
for v in best_nutcracker.result:
locations=[]
if not best_nutcracker.result[v]:
continue
for p in nutcracker.result[v]:
locations.append(node_point[p])
m=plot_locations(m,locations,color_list[cnt])
cnt+=1
return m
# %%
# ### 基础算法
# In[4]:
# 种群数量
population_num=20
# 储存数量
store_num=5
# 迭代次数
iteration_num=100
# 探索概率
exploring_probability=0.5
# 飞行距离
distance=2
# 生成初始种群
population=get_population(population_num)
# 最优个体
best_nutcracker=get_best_nutcracker(population)
# 迭代求解
record=[best_nutcracker.get_fitness()]
best_population=sorted(population, key=lambda x: x.get_fitness())[-store_num:]
for it in tqdm(range(iteration_num)):
for i in range(len(population)):
nutcracker=population[i]
# 觅食阶段
nutcracker=forage(nutcracker,population)
# 储存阶段
best_population=store(nutcracker,best_population)
# 缓存搜索阶段
nutcracker=search(nutcracker,best_population)
# 更新个体
population[i]=nutcracker
# 更新最优个体
if nutcracker.get_fitness()>best_nutcracker.get_fitness():
best_nutcracker=deepcopy(nutcracker)
record.append(best_nutcracker.get_fitness())
plot_convergence([record])
m=plot_route(best_nutcracker)
m.save('basis.html')
# %%
# ### 改进算法
# In[5]:
# 种群数量
population_num=20
# 储存数量
store_num=5
# 迭代次数
iteration_num=100
# 探索概率
exploring_probability=0.5
# 飞行距离
distance=2
# 生成初始种群
population=get_population(population_num)
# 最优个体
best_nutcracker=get_best_nutcracker(population)
# 迭代求解
record1=[best_nutcracker.fitness]
best_population=sorted(population, key=lambda x: x.fitness)[-store_num:]
for it in tqdm(range(iteration_num)):
for i in range(len(population)):
nutcracker=population[i]
# 觅食阶段
new_nutcracker=forage(nutcracker,population)
dert_fitness=new_nutcracker.get_fitness()-nutcracker.get_fitness()
if dert_fitness>0 or random.random()<np.exp(dert_fitness/(it+1)):
nutcracker=deepcopy(new_nutcracker)
# 储存阶段
best_population=store(nutcracker,best_population)
# 缓存搜索阶段
nutcracker=new_search(nutcracker,best_population)
# 更新个体
population[i]=nutcracker
# 更新最优个体
if nutcracker.fitness>best_nutcracker.fitness:
best_nutcracker=deepcopy(nutcracker)
record1.append(best_nutcracker.fitness)
plot_convergence([record1])
m=plot_route(best_nutcracker)
m.save('improve.html')
# %%
# 整数转二进制
def toBit(num, length):
bit = []
for i in range(length - 1, -1, -1):
bit.append(int(num / (supply_point_num + cold_storage_num) ** i))
num -= bit[-1] * (supply_point_num + cold_storage_num) ** i
return bit
# 麻雀个体
class Sparrow:
def __init__(self, individual):
self.individual = individual
self.fitness = self.get_fitness()
def get_fitness(self):
fitness = 0
result = self.decode()
# 冷库建设成本
bit = toBit(self.individual[0], vehicle_num)
cold_set = set()
for b in bit:
if b >= supply_point_num:
cold_set.add(b - supply_point_num)
fitness += sum([cold_storage_fix_cost[c] for c in cold_set]) / (5 * 365)
# 车辆运输成本
for i in result:
if result[i]:
fitness += vehicle_fix_cost[i]
cur_point = bit[i]
for j in result[i]:
jj = j + supply_point_num + cold_storage_num
fitness += vehicle_unit_cost[i] * distance_matrix[cur_point, jj]
cur_point = jj
# 需求延误成本
for j in range(demand_point_num):
min_arrive_time = 1e8
max_arrive_time = 0
for i in result:
if j in result[i]:
min_arrive_time = min(min_arrive_time, result[i][j]['time']['t1'])
max_arrive_time = max(max_arrive_time, result[i][j]['time']['t1'])
fitness += a1 * max(0, time_window[j][0] - min_arrive_time)
fitness += a2 * max(0, max_arrive_time - time_window[j][1])
self.fitness = 1 / fitness
return 1 / fitness
def decode(self):
result = {}
bit = toBit(self.individual[0], vehicle_num)
demand = deepcopy(demand_matrix)
for i in self.individual[1]:
result[i] = {}
serve_order = self.individual[2 + i]
capacity = deepcopy(vehicle_capacity[i])
# 计算开始时间
cur_time = distance_matrix[0, bit[i]] / vehicle_speed[i]
cur_point = bit[i]
result[i][cur_point] = {}
result[i][cur_point]['serve'] = {0: 0, 1: 0, 2: 0}
result[i][cur_point]['time'] = {'t1': cur_time, 't2': cur_time, 't3': cur_time}
for j in serve_order:
jj = j + supply_point_num + cold_storage_num
# 车辆没有剩余容量
if sum(capacity) == 0:
break
# 需求点没有剩余需求
if sum([demand[j, p] for p in range(product_type)]) == 0:
continue
result[i][j] = {}
# 计算需求量
result[i][j]['serve'] = {}
for p in range(product_type):
min_num = min(demand[j, p], capacity[p])
demand[j, p] -= min_num
capacity[p] -= min_num
result[i][j]['serve'][p] = min_num
# 计算时间
arrive_time = cur_time + distance_matrix[cur_point, jj] / vehicle_speed[i]
satrt_serve_time = max(arrive_time, time_window[j][0])
departure_time = satrt_serve_time + time_window[j][2]
result[i][j]['time'] = {'t1': arrive_time, 't2': satrt_serve_time, 't3': departure_time}
cur_time = departure_time
cur_point = j
return result
# 生成个体
def gen_sparrow():
num = randint(0, (supply_point_num + cold_storage_num) ** vehicle_num - 1)
vehicle_order = [i for i in range(vehicle_num)]
random.shuffle(vehicle_order)
serve_order = []
for i in range(vehicle_num):
cur_order = [j for j in range(demand_point_num)]
random.shuffle(cur_order)
serve_order.append(cur_order)
individual = [num] + [vehicle_order] + serve_order
sparrow = Sparrow(individual)
return sparrow
# 生成种群
def get_population(num):
population = []
for i in range(num):
population.append(gen_sparrow())
return population
# 获取最优个体
def get_best_sparrow(population):
best_fitness = float('inf')
best_sparrow = None
for sparrow in population:
if sparrow.fitness < best_fitness:
best_fitness = sparrow.fitness
best_sparrow = sparrow
return best_sparrow
# 混沌序列生成器(Logistic映射)
def logistic_map(x, r=3.99):
return r * x * (1 - x)
# 混沌初始化种群
def chaos_initialize_sparrows(population_size):
population = []
x = 0.5 # 初始值
for _ in range(population_size):
individual = []
for _ in range(vehicle_num):
x = logistic_map(x)
num = int(x * ((supply_point_num + cold_storage_num) ** vehicle_num))
vehicle_order = [i for i in range(vehicle_num)]
random.shuffle(vehicle_order)
serve_order = []
for i in range(vehicle_num):
cur_order = [j for j in range(demand_point_num)]
random.shuffle(cur_order)
serve_order.append(cur_order)
individual = [num] + [vehicle_order] + serve_order
population.append(Sparrow(individual))
return population
# 觅食阶段
def forage(sparrow, population):
# 随机探索
if random.random() < exploring_probability:
individual = sparrow.individual
individual[0] = randint(0, (supply_point_num + cold_storage_num) ** vehicle_num - 1)
sparrow = Sparrow(individual)
return sparrow
# 最优探索
else:
best_sparrow = get_best_sparrow(population)
individual = sparrow.individual
best_individual = best_sparrow.individual
individual[0] = best_individual[0]
sparrow = Sparrow(individual)
return sparrow
# 储存阶段
def store(sparrow, best_population):
new_best_population = deepcopy(best_population)
new_best_population.append(sparrow)
new_best_population = sorted(new_best_population, key=lambda x: x.fitness)
return new_best_population[1:]
# Levy飞行距离
def levy_distance(nutcracker1, nutcracker2):
individual1 = nutcracker1.individual
individual2 = nutcracker2.individual
distance = abs(individual1[0] - individual2[0]) / max(individual1[0], individual2[0])
for i in range(vehicle_num + 1):
ii = i + 1
sum1 = 0
for j in range(len(individual1[ii])):
sum1 += j * individual1[ii][j]
sum2 = 0
for j in range(len(individual2[ii])):
sum2 += j * individual2[ii][j]
distance += abs(sum1 - sum2) / max(sum1, sum2)
return distance
# 缓存搜索阶段
def search(sparrow, best_population):
individual = sparrow.individual
for cur_sparrow in best_population:
if levy_distance(sparrow, cur_sparrow) > distance:
continue
cur_individual = cur_sparrow.individual
new_individual = []
for i in range(len(individual)):
if randint(0, 1):
new_individual.append(individual[i])
else:
new_individual.append(cur_individual[i])
new_sparrow = Sparrow(new_individual)
if new_sparrow.fitness > sparrow.fitness:
sparrow = deepcopy(new_sparrow)
return sparrow
# 绘制收敛图
def plot_convergence(convergence_records):
num_curves = len(convergence_records)
for i in range(num_curves):
cur = convergence_records[i]
convergence_records[i] = [1 / i for i in cur]
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w']
plt.figure(figsize=(20, 10))
for i, record in enumerate(convergence_records):
iterations = list(range(1, len(record) + 1))
plt.plot(iterations, record, marker='o', label=f'Curve {i+1}', color=colors[i % len(colors)])
plt.title('Convergence Plots')
plt.xlabel('Iteration')
plt.ylabel('Cost')
plt.legend()
plt.grid(False)
plt.show()
# %%
# 种群数量
population_num=20
# 储存数量
store_num=5
# 迭代次数
iteration_num=100
# 探索概率
exploring_probability=0.5
# 飞行距离
distance=2
# 生成初始种群
population=get_population(population_num)
# 最优个体
best_sparrow = get_best_sparrow(population)
# 迭代求解
record2 = [best_sparrow.fitness]
best_population = sorted(population, key=lambda x: x.fitness)[-store_num:]
for it in tqdm(range(iteration_num)):
for i in range(len(population)):
sparrow = population[i]
# 觅食阶段
sparrow = forage(sparrow, population)
# 储存阶段
best_population = store(sparrow, best_population)
# 缓存搜索阶段
sparrow = search(sparrow, best_population)
# 更新个体
population[i] = sparrow
# 更新最优个体
if sparrow.fitness > best_sparrow.fitness:
best_sparrow = deepcopy(sparrow)
record2.append(best_sparrow.fitness)
plot_convergence([record2])
# %%
# 绘制收敛图的函数
def plot_convergence(convergence_records):
num_curves = len(convergence_records)
for i in range(num_curves):
cur = convergence_records[i]
convergence_records[i] = [1 / i for i in cur]
colors = ['b', 'g', 'r'] # 定义三条记录的颜色
plt.figure(figsize=(20, 10))
# 定义每条曲线的中文标签
labels = ['NOA', 'NOA_SA', 'SSA']
for i, record in enumerate(convergence_records):
iterations = list(range(1, len(record) + 1))
plt.plot(iterations, record, marker='o', label=labels[i], color=colors[i])
plt.title('Convergence Plots')
plt.xlabel('Itterations')
plt.ylabel('Cost')
plt.legend()
plt.grid(False)
plt.show()
convergence_records = [record, record1, record2]
print(f'NOA:{record}')
print(f'NOA_SA:{record1}')
print(f'SSA:{record2}')
# 调用函数绘制图表
plot_convergence(convergence_records)
**需软件开发兼职接项目,请通过手机端搜小#程#序: "黄页小艺"** 。
这段代码实现了一个基于星雀(Nutcracker)和麻雀(Sparrow)算法的物流配送路径规划问题求解程序,主要功能包括以下几个方面:
一、问题定义与参数设置
- 定义了物流配送中的各种参数,如需求点数量、供应点数量、冷库数量、产品种类、车辆数等。
- 生成了需求矩阵、时间窗、车辆容量、车辆承重和体积、车辆速度和行驶距离、车辆成本、产品重量和体积、冷库建设成本等数据。
- 定义了节点坐标和距离矩阵。
二、算法实现
-
整数转二进制函数 :
toBit
函数将一个整数转换为特定长度的二进制表示,用于后续的编码和解码操作。 -
个体类定义:
Nutcracker
类表示星雀个体,包含个体的编码、解码和适应度计算方法。解码过程根据个体编码确定车辆的服务顺序和路径,计算各种成本(冷库建设成本、车辆运输成本、需求延误成本)作为适应度。Sparrow
类表示麻雀个体,功能与星雀个体类似,也包含编码、解码和适应度计算方法。
-
生成个体和种群:
gen_nutcracker
函数生成星雀个体,包括随机生成的车辆分配、车辆顺序和服务顺序。gen_sparrow
函数生成麻雀个体,方式与生成星雀个体类似。get_population
函数根据给定数量生成星雀或麻雀种群。
-
获取最优个体 :
get_best_nutcracker
和get_best_sparrow
函数分别用于在星雀和麻雀种群中获取适应度最高的个体。 -
觅食阶段 :
forage
函数实现了星雀和麻雀的觅食行为,包括随机探索和最优探索两种方式。 -
储存阶段 :
store
函数将当前个体加入到最佳种群中,并返回更新后的最佳种群。 -
缓存搜索阶段:
search
函数根据 Levy 飞行距离在最佳种群中进行搜索,生成新的个体,如果新个体适应度更高则更新当前个体。new_search
函数在search
函数的基础上增加了交换操作,进一步探索解空间。
-
混沌初始化种群 :
chaos_initialize_sparrows
函数使用 Logistic 映射生成混沌序列,用于初始化麻雀种群,增加种群的多样性。 -
Levy 飞行距离计算 :
levy_distance
函数计算两个个体之间的 Levy 飞行距离,用于缓存搜索阶段判断个体之间的相似性。
三、算法运行与结果展示
-
基础算法运行:
- 设置种群数量、储存数量、迭代次数、探索概率和飞行距离等参数。
- 生成初始种群,找到最优个体。
- 通过迭代进行觅食、储存和缓存搜索等操作,更新种群和最优个体,并记录最优个体的适应度。
- 绘制收敛图,展示算法在迭代过程中适应度的变化情况。
- 绘制路线图,使用 Folium 库在地图上展示车辆的行驶路径。
-
改进算法运行:与基础算法类似,但在觅食阶段增加了基于适应度差值和随机概率的接受新个体的条件。
-
麻雀算法运行:
- 定义麻雀个体和相关操作,与星雀算法类似。
- 生成麻雀种群,进行迭代求解,记录适应度并绘制收敛图。
-
综合结果展示:
- 定义绘制收敛图的函数
plot_convergence
,可以同时展示多个算法的收敛情况,并为每条曲线添加中文标签。 - 将三种算法(基础算法、改进算法、麻雀算法)的收敛记录合并,调用
plot_convergence
函数绘制综合收敛图。
- 定义绘制收敛图的函数
总体来说,这段代码通过实现不同的优化算法来解决物流配送中的路径规划问题,包括确定车辆的分配、服务顺序和路径,以最小化总成本。同时,通过绘制收敛图和路线图展示算法的性能和结果。
需软件开发兼职接项目,请通过手机端搜小#程#序: "黄页小艺" 。