有N件物品和一个容量为V的背包。第i件物品的体积是c(i),价值是w(i)。求解将哪些物品放入背包可使物品的体积总和不超过背包的容量,且价值总和最大。
假设物品数量为10,背包的容量为300。每件物品的体积为[95,75,23,73,50,22,6,57,89,98],每件物品的价值为[89,59,19,43,100,72,44, 16,7,64]。
其中:初始化群体粒子个数为N=100,粒子维数(即二进制编码长度)D=10,最大迭代次数为T=200,学习因子c1=c2=1.5,惯性权重最大值为wmax=0.8,惯性权重最小值为wmin=0.4,速度最大值为vmax=10,速度最小值为Vmin=-10。
要求生成适应度进化曲线图,x轴为迭代次数,y轴为适应度值
import numpy as np
import matplotlib.pyplot as plt
# 初始化参数
N = 100 # 群体粒子个数
D = 10 # 粒子维数(物品数量)
T = 200 # 最大迭代次数
c1 = 1.5 # 学习因子1
c2 = 1.5 # 学习因子2
Wmax = 0.8 # 惯性权重最大值
Wmin = 0.4 # 惯性权重最小值
Vmax = 10 # 速度最大值
Vmin = -10 # 速度最小值
V = 300 # 背包容量
C = np.array([95, 75, 23, 73, 50, 22, 6, 57, 89, 98]) # 物品体积
W = np.array([89, 59, 19, 43, 100, 72, 44, 16, 7, 64]) # 物品价值
afa = 2 # 惩罚函数系数
# 初始化种群个体(限定位置和速度)
x = np.random.randint(2, size=(N, D)) # 随机获得二进制编码的初始种群
v = np.random.rand(N, D) * (Vmax - Vmin) + Vmin
# 适应度函数
def func4(f, C, W, V, afa):
fit = np.sum(f * W)
TotalSize = np.sum(f * C)
if TotalSize <= V:
return fit
else:
return fit - afa * (TotalSize - V)
# 初始化个体最优位置和最优值
p = x.copy()
pbest = np.zeros(N)
for i in range(N):
pbest[i] = func4(x[i], C, W, V, afa)
# 初始化全局最优位置和最优值
g = np.zeros(D)
gbest = -np.inf
for i in range(N):
if pbest[i] > gbest:
g = p[i].copy()
gbest = pbest[i]
gb = np.zeros(T)
# 按照公式依次迭代直到满足精度或者迭代次数
for i in range(T):
for j in range(N):
# 更新个体最优位置和最优值
if func4(x[j], C, W, V, afa) > pbest[j]:
p[j] = x[j].copy()
pbest[j] = func4(x[j], C, W, V, afa)
# 更新全局最优位置和最优值
if pbest[j] > gbest:
g = p[j].copy()
gbest = pbest[j]
# 计算动态惯性权重值
w = Wmax - (Wmax - Wmin) * i / T
# 更新位置和速度值
v[j] = w * v[j] + c1 * np.random.rand(D) * (p[j] - x[j]) + c2 * np.random.rand(D) * (g - x[j])
# 边界条件处理
v[j] = np.clip(v[j], Vmin, Vmax)
# Sigmoid函数将速度映射到0-1之间,并更新位置
vx = 1 / (1 + np.exp(-v[j]))
x[j] = (vx > np.random.rand(D)).astype(int)
# 记录历代全局最优值
gb[i] = gbest
gbi=max(gb)
print("最优个体的选择:", g)
print("最优价格",gbi)
plt.plot(gb)
plt.xlabel("The number of iterations")
plt.ylabel("Fitness")
plt.title("Fitness Evolution Curve")
plt.show()