粒子群优化PSO
受到鸟群捕食启发。是一种群体智能算法,利用群体中的个体对信息的共享,
粒子群算法的具体流程包括以下步骤:
初始化粒子群:
随机生成一系列具有随机速度和位置的粒子,同时记录每个粒子的个体历史最优位置和全局历史最优位置。
粒子更新:
根据当前的位置和速度、个体历史最优位置及全局历史最优位置等信息,计算粒子的新速度和新位置。速度改变的大小受到加速度限制器和阻力因子等限制。
具体公式如下:
for i=1 to 粒子数目 do
①.计算适应度值f(x_i)
②.更新粒子速度v_i和位置x_i
v_i(k+1)=wv_i(k)+c1r1(x_pbesti(k)-x_i(k))+c2r2(x_gbest(k)-x_i(k))
x_i(k+1)=x_i(k)+v_i(k+1)
end for
其中,v_i(k)为第i个粒子在第k次迭代时的速度,x_i(k)为第i个粒子在第k次迭代时的位置,x_pbesti(k)为第i个粒子在第k次迭代中所取得的最优位置,x_gbest(k)为全局历史最优位置,w、c1、c2为权值系数,r1、r2为随机数。
评价粒子群:
对所有粒子根据其新位置计算适应度值,并更新个体历史最优位置和全局历史最优位置。
终止条件判断:
如果达到预定的终止条件,例如满足最大迭代次数或者预设的目标值时,结束迭代并输出结果。否则,继续进行迭代,回到步骤2。
通过不断的迭代,粒子将逐渐聚集在全局最优解附近,最终得出最优解。
在粒子群算法中,c1和c2被称为加速常数,它们是控制粒子运动的参数。c1和c2通常被设置为常数,在算法中保持不变。c1和c2的作用是控制粒子在搜索空间中移动的速度和方向。
c1和c2的具体定义如下:
在粒子群算法中,particles指的是粒子的集合,也可以称为粒子群。在算法执行过程中,每个粒子都代表着问题空间中的一个可能解,而particles则代表着粒子群的集合。
每个粒子都有自己的位置和速度,通过更新位置和速度,粒子可以移动到新的位置,以期望找到更优秀的解决方案。粒子群中的所有粒子都是同时更新的,他们通过彼此之间的交换信息来实现全局搜索。
在粒子群算法中,每个粒子都有自己的历史最佳位置(pbest)和全局最佳位置(gbest)。
自身历史最佳位置是指当前粒子已知的它自己达到的最优位置,即粒子在搜索过程中达到的最佳解。每个粒子通过比较自己历史上所到达的最佳位置和当前位置,来更新自身历史最佳位置。每个粒子都会记录自己的历史最佳位置,以便在后续迭代过程中进行比较和更新。
全局最佳位置是指整个粒子群已知的所有粒子中,目前达到的最优位置。在算法开始时,通常会将第一个粒子视为全局最佳位置,然后在迭代过程中,通过比较每个粒子的自身历史最佳位置和当前全局最佳位置,来更新全局最佳位置。所有的粒子共享同一个全局最佳位置,以便在算法迭代的过程中,能够更好地指导粒子的搜索方向,帮助其更快地达到最优解。
# 实现,你可以借此更好地理解如何在粒子群算法中应用
# VRP:
#
# ```python
import random
class Particle:
def __init__(self, vrp, position):
self.vrp = vrp
self.position = position
self.velocity = self.__initialize_velocity() # 初始化时速度为0
self.pbest = self.position # 初始最优解为当前位置
self.pbest_cost = self.__evaluate(self.pbest) # 记录初始最优解的cost
self.gbest = None
self.gbest_cost = float('inf')
def __initialize_velocity(self):
velocity = []
for i in range(len(self.vrp.customers)):
velocity.append(random.uniform(-1, 1)) # 初始化速度范围为-1到1
return velocity
def __evaluate(self, solution):
# 计算当前解的cost
cost = 0
for route in solution:
demand = 0
route_cost = 0
if isinstance(route, int):
route = [route]
for customer in route:
demand += self.vrp.customers[customer][1]
route_cost += self.vrp.distance_matrix[customer][route[-1]] # 路径长度 = 客户距离 + 已经服务的客户到仓库的距离
route_cost += self.vrp.distance_matrix[0][route[0]] # 起点到第一个客户距离
route_cost += self.vrp.distance_matrix[0][route[-1]] # 最后一个客户到仓库距离
if demand > self.vrp.vehicle_capacity:
route_cost += self.vrp.penalty * (demand - self.vrp.vehicle_capacity)
cost += route_cost
return cost
def update_velocity(self, w, c1, c2, gbest_position):
# 更新速度
# 先判断 gbest_position 和 pbest 是否为 None
if not gbest_position:
return
if not self.position or not self.pbest:
return
velocity_length = len(self.velocity)
position_length = len(self.position)
pbest_length = len(self.pbest)
gbest_position_length = len(gbest_position)
if velocity_length != position_length or velocity_length != pbest_length or velocity_length != gbest_position_length:
return
for i in range(len(self.velocity)):
r1 = random.uniform(0, 1)
r2 = random.uniform(0, 1)
cognitive = c1 * r1 * (self.pbest[i] - self.position[i])
print("velocity:", self.velocity)
print("pbest:", self.pbest)
print("position:", self.position)
print("gbest_position:", gbest_position)
social = c2 * r2 * (gbest_position[i] - self.position[i])
self.velocity[i] = w * self.velocity[i] + cognitive + social
def update_position(self):
# 根据新速度更新当前位置
if not self.position: # 如果 self.position 列表为空,则不进行更新操作
return
new_position = []
for i in range(len(self.vrp.customers)):
if i >= len(self.position): # 检查 i 是否超出了 self.position 的长度
break
if self.position[i] == 0:
continue
new_pos = self.position[i] + self.velocity[i]
if new_pos < 1:
new_pos = 1
elif new_pos > len(self.vrp.customers) - 1:
new_pos = len(self.vrp.customers) - 1
new_position.append(int(new_pos))
self.position = new_position
def update_pbest(self):
# 如果当前位置比已知最优解更好,则更新最优解
new_cost = self.__evaluate(self.position)
if new_cost < self.pbest_cost:
self.pbest = self.position
self.pbest_cost = new_cost
def update_gbest(self, gbest_position, gbest_cost):
# 更新全局最优解
if gbest_cost < self.gbest_cost:
self.gbest = gbest_position
self.gbest_cost = gbest_cost
class VRP:
def __init__(self, distance_matrix, customers, num_vehicles, vehicle_capacity, max_iterations=100, penalty=1000,
w=0.8, c1=0.5, c2=0.5, swarm_size=50):
self.distance_matrix = distance_matrix
self.customers = customers
self.num_vehicles = num_vehicles
self.vehicle_capacity = vehicle_capacity
self.max_iterations = max_iterations
self.penalty = penalty
self.w = w
self.c1 = c1 #什么意思
self.c2 = c2
self.swarm_size = swarm_size
def solve(self):
particles = [Particle(self, self.__initialize_particle()) for i in range(self.swarm_size)]
gbest = None
gbest_cost = float('inf')
for i in range(self.max_iterations):
for particle in particles:
particle.update_velocity(self.w, self.c1, self.c2, gbest)
particle.update_position()
particle.update_pbest()
if particle.pbest_cost < gbest_cost:
gbest = particle.pbest
gbest_cost = particle.pbest_cost
particle.update_gbest(gbest, gbest_cost)
return gbest, gbest_cost
def __initialize_particle(self):
# 初始化一个解
customers = list(range(1, len(self.customers)))
random.shuffle(customers)
routes = []
for i in range(self.num_vehicles):
route = []
remaining_capacity = self.vehicle_capacity
for j in customers:
if remaining_capacity >= self.customers[j][1]:
route.append(j)
remaining_capacity -= self.customers[j][1]
routes.append(route)
return [0] + sum(routes, []) + [0] * (len(self.customers) - len(sum(routes, [])))
# ```
#
# 然后你可以创建一个
# VRP
# 对象,并调用
# solve()
# 方法来解决问题:
#
# ```python
distance_matrix = [
[0, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 30, 0]
]
customers = [
(0, 0),
(1, 10),
(2, 15),
(3, 20)
]
vrp = VRP(distance_matrix, customers, num_vehicles=2, vehicle_capacity=30)
solution, cost = vrp.solve()
print("Solution: ", solution)
print("Cost: ", cost)
# ```
#
# 以上仅为一个简单实现,仍可进行参数调优以得到更好的结果。