Python——模拟退火在背包问题上的运用(详细代码)

一、模拟退火简介

二、详细代码

import math
import random
import matplotlib.pyplot as plt

def init_population(n):  
    '''生成一个种群,个体为全排列的随机排列'''
    population = []
    indivdul = 100  #个体数为100
    for i in range(indivdul):
        cs = [i for i in range(1,n+1)]
        random.shuffle(cs) #打乱
        population.append(cs)
    return population



def ff_popu(population,n,v1,v2):  
    '''传入一个种群,返回一个函数值列表'''
    ys = []
    for i in population:
        cost_sum = 0
        location  = i
        for j in range(n):
            for k in range(n):
                loca1 = location.index(j+1)
                loca2 = location.index(k+1)
                cost = v2[j][k]*v1[loca1][loca2]  #核心计算函数
                cost_sum = cost_sum + cost
        ys.append(cost_sum)
        index = ys.index(min(ys))
        #best = population[index]
    return ys

def ff_indivdul(i,n,v1,v2):
    '''传入一个个体,返回一个值'''
    cost_sum = 0
    location  = i
    for j in range(n):
        for k in range(n):
            loca1 = location.index(j+1)
            loca2 = location.index(k+1)
            cost = v2[j][k]*v1[loca1][loca2]  #核心计算函数
            cost_sum = cost_sum + cost
    return cost_sum



def neig(population,n,T,v1,v2):
    '''
    传入一个种群
    对种群中的每个个体产生邻域
    根据退火原理来判断是否接受这个新解
    返回一个新的种群
    '''
    popu_new = []
    for i in population:
        #随机生成两个数,让个体中这两个交换
        r1 = random.randint(0,len(i)-1)
        r2 = random.randint(0,len(i)-1)
        
        i_after = i[:]
        i_after[r1] = i[r2]
        i_after[r2] = i[r1]
        #分别计算初始值和邻域值
        y = ff_indivdul(i, n, v1, v2)
        y_after = ff_indivdul(i_after, n, v1, v2)
        E = y_after - y 
        if E < 0:
            i = i_after
        else:
            proba = random.random()
            f = math.exp(-(E/T))
            if proba <= f:
                i = i_after
        popu_new.append(i)
    return popu_new
        
def read():
    with open('D:/学习文件/大三上/科研课堂/qap-problems/QAP32.dat','r',encoding='utf-8') as f:   
        comments = f.read().splitlines()
    n = eval(comments[0])
    v11 = comments[2:2+n]
    v22 = comments[3+n:3+n+n]
    v1 = []
    v2 = []
    for i in v11:
        int_list = list(map(int, i.split()))
        v1.append(int_list)
    for i in v22:
        int_list = list(map(int, i.split()))
        v2.append(int_list)
    return v1,v2,n

def main():
    v1,v2,n = read()
    population = init_population(n)
    #evolution = 1000
    print(min(ff_popu(population,n,v1,v2)))
    T = 30  #这个是初始温度
    plt_y = []
    while (T > 2):
        population = neig(population,n,T,v1,v2)
        print(min(ff_popu(population,n,v1,v2)))
        plt_y.append(min(ff_popu(population,n,v1,v2)))
        T = T - 0.1  #每次温度减去0.1
    plt.plot(plt_y)
        
main()

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个简单的模拟退火算法背包问题Python代码: ```python import random import math # 背包问题 class Knapsack: def __init__(self, values, weights, capacity): self.values = values # 物品价值 self.weights = weights # 物品重量 self.capacity = capacity # 背包容量 # 计算当前解的价值和重量 def calc_value_weight(self, solution): value = 0 # 解的价值 weight = 0 # 解的重量 for i, s in enumerate(solution): if s == 1: value += self.values[i] weight += self.weights[i] return value, weight # 评价函数 def evaluate(self, solution): value, weight = self.calc_value_weight(solution) if weight > self.capacity: # 超过背包容量,惩罚 return -1 else: return value # 模拟退火算法 def simulated_annealing(knapsack, init_solution, init_temperature, cooling_rate, iter_per_temp): current_solution = init_solution # 当前解 best_solution = init_solution # 最优解 temperature = init_temperature # 初始温度 while temperature > 1e-6: for i in range(iter_per_temp): # 产生邻域解 neighbor = current_solution[:] index = random.randint(0, len(neighbor)-1) neighbor[index] = 1 - neighbor[index] # 计算评价函数的差 delta = knapsack.evaluate(neighbor) - knapsack.evaluate(current_solution) # 判断是否接受邻域解 if delta > 0 or math.exp(delta/temperature) > random.random(): current_solution = neighbor[:] # 更新最优解 if knapsack.evaluate(current_solution) > knapsack.evaluate(best_solution): best_solution = current_solution[:] # 降温 temperature *= cooling_rate return best_solution # 测试 values = [60, 100, 120, 150, 200] weights = [10, 20, 30, 40, 50] capacity = 100 knapsack = Knapsack(values, weights, capacity) init_solution = [0, 0, 0, 0, 0] init_temperature = 100 cooling_rate = 0.95 iter_per_temp = 100 best_solution = simulated_annealing(knapsack, init_solution, init_temperature, cooling_rate, iter_per_temp) print("背包问题的最优解为:", best_solution) ``` 上述代码的输出结果可能为: ``` 背包问题的最优解为: [0, 1, 1, 1, 1] ``` 表示第2到第5个物品被放入背包,而第1个物品没有被放入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值