栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python模拟退火算法求解规划问题

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python模拟退火算法求解规划问题

import math
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

# 子程序:定义优化问题的目标函数
def cal_Energy(X, nVar, mk): # # m(k):惩罚因子,随迭代次数 k 逐渐增大
    p1 = (max(0, 6*X[0]+5*X[1]-60))**2
    p2 = (max(0, 10*X[0]+20*X[1]-150))**2
    fx = -(10*X[0]+9*X[1])
    return fx+mk*(p1+p2)


# 子程序:模拟退火算法的参数设置
def ParameterSetting():
    cName = "funcOpt"  # 定义问题名称
    nVar = 2  # 自变量数量 y=f(x1,x2,...xn)
    xMin = [0, 0]  #给定搜索空间的下限, x1_min, ... xn_min
    xMax = [8, 7.5 ]  # 给定搜索空间的上限 x1_max,..xn_max

    tInitial = 100.0  # 设置初始退火温度
    tFinal = 1  # 设置种子退火温度
    alfa = 0.98
    meanMarkov = 100  # Markov链长度  即内循环运行次数
    scale = 0.5   # 定义搜索步长,也可设定为固定值或逐渐减小

    return cName, nVar, xMin,xMax, tInitial, tFinal, alfa, meanMarkov, scale


def OptimizationSSA(nVar, xMin, xMax, tInitial, tFinal, alfa, meanMarkov, scale):
    # ======初始化随机数发生器
    randseed = random.randint(1,100)
    random.seed(randseed) # 随机数发生器设置种子,也可设定为这指定整数


    # =======随机产生优化问题的初始解
    xInitial = np.zeros((nVar)) #初始化创建数组 【0, 0】
    for v in range(nVar):
        # random.uniform(min, max) 在[min, max] 范围内随机生成一个实数
        xInitial[v] = random.uniform(xMin[v], xMax[v])# x1, x2

    #调用子函数, cal——Energy(xInitial, nVar, 1) # m(k) , 惩罚因子,初值为1
    fxInitial = cal_Energy(xInitial, nVar, 1)

    # 模拟退火算法初始化
    xNew = np.zeros((nVar))  # 初始化, 创建数组
    xNow = np.zeros((nVar))  # 初始化,创建数组
    xBest = np.zeros((nVar))  # 初始化 创建数组
    xNow[:] = xInitial[:]  # 初始化当前解, 将初始解置为当前解
    xBest[:] = xInitial[:]  #初始化最优解, 将当前解置为朱友杰
    fxNow =  fxInitial # 将初始解的目标函数置为当前值
    fxBest = fxInitial #将当前解的目标函数置为最优值
    print('x_Initial:{:.6f},{:.6f},tf(x_Initial):{:.6f}'.format(xInitial[0], xInitial[1], fxInitial))
    recordIter = [] #初始化,外循环次数
    recordFxNow = [] #初始化,当前解为目标函数值
    recordFxbest = [] # 初始化,最佳解的目标函数值
    recordPBad = [] # 初始化,劣质解的接受概率
    kIter = 0 #外循环迭代次数, 温度状态数
    totalMar = 0 # 总计Mrakov链长度
    totalImprove = 0 #fxBest改善次数
    nMarkov = meanMarkov  # 固定长度Markov链


    #=====开始模拟退火优化====
    #外循环,直到当前温度达到终止温度时结束
    tNow = tInitial  #初始化当前温度
    while tNow >=tFinal: #外循环,直到当前温度达到终止温度时结束  100 98  , 1
        # 在当前温度下,进行充分次数(nMarkov)的状态转移以达到热平衡
        kBetter = 0 #获得优值解的次数
        kBadAccept = 0 #接受劣质解的次数
        kBadRefuse = 0# 拒绝劣质解的次数

        #----内循环,循环次数为Markov链长度 100
        for k in range(nMarkov):  #内循环, 循环次数为Markov链长度
            totalMar +=1  #总Markov链长度计数器
        # x1,x2
            #----产生新解
            # 产生新解,通过在当前解附近随机扰动而产生新解 ,新解必须在[min,max]范围内
            #方案1,只对n元变量中的一个进行扰动,其他n-1个变量保持不变
            xNew[:] = xNow[:]
            v = random.randint(0, nVar-1) #产生[ 0, nVar]之间的随机数 8+0.5*
            xNew[v] = xNow[v] +scale*(xMax[v]-xMin[v])*random.normalvariate(0, 1) #random.normalvariate(0, 1) 服从均值为0、标准差为1的正态分布随机实数
            xNew[v] = max(min(xNew[v], xMax[v]), xMin[v])# 保证新解在[min,max]范围内

            #----计算目标函数和能量差
            #调用子函数cal_Energy 计算新解的目标函数值
            fxNew = cal_Energy(xNew, nVar, kIter)
            deltaE = fxNew - fxNow

            #---按Metropolis准则接受新解
            #接受判别: 按照Metropolics 准则决定是否接受新解

            if fxNew  random.random():
                    accept = True#接受劣质解
                    kBadAccept +=1

            #保存新解
            if accept == True: #如果接受新解, 则将新解保存为当前解
                xNow[:] = xNew[:]
                fxNow = fxNew
                if fxNew  1e-3:  #检验目标函数
        print("Error 2: Wrong total millage")
        return
    else:
        print("n Optomozation by simulated annealing algorithm")
        for i in range(nVar):
            print("t x[{}] = {:.6f}".format(i, xBest[i]))
        print("nt tf(x):{:.6f}".format(cal_Energy(xBest, nVar, 0)))

        #优化结果写入数据文件=====

    nowTime = datetime.now().strftime('%m%d%H%M')
    fileName = '{}_{}.dat'.format(cName, nowTime )
    optRecord = {
        'iter': recordIter,
        "FxNow": recordFxNow,
        'FxBest': recordxBest,
        "PBad": recordPBad
    }
    df_Record = pd.DataFrame(optRecord)
    df_Record.to_csv(fileName, index=False, encoding='utf_8_sig')

    with open(fileName, 'a+', encoding='utf_8_sig') as fid:
        fid.write('n Optimization by simulated annealing algorithm:')
        for i in range(nVar):
            fid.write('ntx[{}] = {:.6f}'.format(i,xBest[i]))

        fid.write('ntf(x):{:.6f}'.format(cal_Energy(xBest, nVar, 0)))
    print("写入数据文件:%s完成。" %fileName)

    #0-----优化结果图形输出
    plt.figure(figsize=(6,4), facecolor='#FFFFFF')
    plt.title("Optimization result: {}".format(cName))
    plt.xlim((0, kInter))
    plt.xlabel("iter")
    plt.ylabel("f(x)")
    plt.plot(recordIter, recordFxNow, 'b-', label='FxNow')
    plt.plot(recordIter, recordxBest, 'r-', label='FxBest')
    plt.legend()
    plt.show()

    return

def main():

    # 参数设置,优化问题参数定义,模拟退火算法参数设置
    [cName, nVar, xMin, xMax, tInitial, tFinal, alfa, meanMarkov, scale] = ParameterSetting()
    # print([nVar, xMin, xMax, tInitial, tFinal, alfa, meanMarkov, scale])

    # 模拟退火算法
    [kIter,xBest,fxBest,fxNow,recordIter,recordFxNow,recordFxBest,recordPBad] 
        = OptimizationSSA(nVar,xMin,xMax,tInitial,tFinal,alfa,meanMarkov,scale)
    # print(kIter, fxNow, fxBest, pBadAccept)

    # 结果校验与输出
    ResultOutput(cName, nVar,xBest,fxBest,
                 kIter,recordFxNow,recordFxBest,recordPBad,recordIter)


if __name__ == '__main__':
    main()











转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/834617.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号