基于遗传退火解决背包问题(python)

我属于一个刚刚踏入这个领域的新手,试着写了一下这段代码,如有不对的地方欢迎批评指正。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib;matplotlib.use('TKAgg')
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
import math
       #冷却列表#
l = 50             #可夫链长度 #在温度为t情况下的迭代次数
k = 0.81            #衰减
s = 0.01            #步长
t = 100             #初温
yz = 1e-8
p = 0               #Metropolis过程中总接受点
eloss = 0.1
#====随机选点 初值设定====

def calc(x):  # 计算背包价值
    f = 0
    h = 0
    xx = 0
    for i in range(n):
        if  x[i] == 1:
            h += W[i]
            f += V[i]
            xx += G[i]
    return h,f,xx
def put(x):  # 随机放入背包中不存在的物品
    while (1 > 0):
        ob = np.random.randint(0, n - 1)
        if (x[ob] == 0):
            x[ob] = 1
            break
def get(x):  # 随机将背包中已经存在的物品取出
    while (1 > 0):
        ob = np.random.randint(0, n - 1)
        if (x[ob] == 1):
            x[ob] = 0
            break
##初始化,N为种群规模,n为染色体长度
def init(N,n):
    C = []
    for i in range(N):
        c = []
        for j in range(n):
            a = np.random.randint(0,2)
            c.append(a)
        C.append(c)
    return C
##评估函数
# x(i)取值为1表示被选中,取值为0表示未被选中
# w(i)表示各个分量的重量,v(i)表示各个分量的价值,w表示最大承受重量
def fitness(C,N,n,W,V,w,G,ccc):
    S = []##用于存储被选中的下标
    F = []## 用于存放当前该个体的最大价值
    for i in range(N):
        s = []
        g = 0
        h = 0  # 重量
        f = 0  # 价值
        for j in range(n):
            if C[i][j]==1:
                if (h+W[j]<=w and g+G[j]<=ccc) :
                    h=h+W[j]
                    f = f+V[j]
                    g = g+G[j]
                    s.append(j)
        S.append(s)
        F.append(f)
    return S,F
##适应值函数,B位返回最大值对应的种族基因下标,y为返回的最大值
def best_x(F,S,N):
    y = 0
    x = 0
    B = [0]*N
    for i in range(N):
        if y 10):
            t = t * k  # 降温
            # print(t)
            # ===在当前温度T下迭代次数====
            for qqq in range(l):
                s, f,ds = calc(r)
                ob = np.random.randint(0, n - 1)  # 随机选取某个物品
                ebs = r.copy()
                if (ebs[ob] == 1):
                    put(ebs)
                    ebs[ob] = 0  # 在背包中则将其拿出,并加入其它物品
                else:  # 不在背包中则直接加入或替换掉已在背包中的物品
                    if (np.random.random() < 0.5):
                        ebs[ob] = 1
                    else:
                        get(ebs)
                        ebs[ob] = 1
                s, e ,df= calc(ebs)
                if (s > w and df > ccc): continue;  # 非法解则跳过
                if (e > y):
                    y = e
                    aa = ebs
                if (e > f):
                    r = ebs
                else:
                    g = 1.0 * (e - f) / t
                    if (np.random.random() < math.exp(g)):  # 概率接受劣解
                        r = ebs
                traee.append(y)
                if aa != 0:
                    jiyin.append(aa)
                C = jiyin
    S, F = fitness(C, m, n, W, V, w,G,ccc)
    B1, y1 = best_x(F, S, m)
    if y1 > y:
        y = y1
    Y.append(y)
print('最大值的取值下标',B1)
print("最大值为:",y)

plt.plot(Y)
plt.title('遗传退火')
plt.show()

结果

下面为以上程序的运行结果,由于遗传算法的种群随机,并且问题比较简单有可能一开始就获得需要的值这都属于正常现象。

基于遗传退火解决背包问题(python)_第1张图片

 

 

你可能感兴趣的:(python,机器学习,开发语言)