Python中的模拟退火,While循环中的变量?

时间:2016-01-12 20:46:00

标签: python while-loop simulated-annealing

成功编写了一个遗传算法,我现在正在编写一个模拟退火程序,用于与GA进行比较,但似乎无法让它达到任何一种最佳状态,更不用说全局算法。

经过一些测试后,我认为问题似乎是将变量传递回while循环。出于测试目的,我已经将代码更改为基本上只接受具有比先前解决方案更低的能量增量的解决方案,因此我应该期望存储最佳解决方案的变量仅显示较低的数字但实际上是波动并且总是返回最多最近的解决方案是否更好。任何帮助将不胜感激。

while temperature >0.01:
    solutionlength = len(Solution)
    NeighbourSolution = Solution
    switch1 = i % solutionlength
    i +=random.randint(0,100)
    switch2 = i % solutionlength
    NeighbourSolution[switch1], NeighbourSolution[switch2] = NeighbourSolution[switch2], NeighbourSolution[switch1]
    EnergyOld = Solution.get_changeover_times()
    EnergyNew = NeighbourSolution.get_changeover_times()
    EnergyDelta = EnergyNew - EnergyOld

    if EnergyDelta < 0:
        acceptanceprob = 1

    else:
        acceptanceprob = 0 #math.exp(-EnergyDelta/temperature)

    if acceptanceprob > 0: #random.random():
        Solution = NeighbourSolution

    if Solution.get_changeover_times() < bestsolution.get_changeover_times():
        bestsolution = Solution

    print (bestsolution.get_changeover_times())

    temperature -= coolingrate

1 个答案:

答案 0 :(得分:0)

问题不在于“将变量传回while循环”,因为您只能将变量传递给函数,而不是循环。

问题是像NeighbourSolution = Solutionbestsolution = Solution这样的行只会使两个名称指向同一个对象。因此,如果您更改,例如Solution您还在更改bestsolution。当然,当您将bestsolution.get_changeover_times()Solution.get_changeover_times()进行比较时,对象的转换时间永远不会小于同一对象的转换时间。

解决方案是制作对象的副本,而不仅仅为其分配一个额外的名称。我不知道您的Solution是什么类型的对象,但如果它是列表子类,您可以使用Solution[:]来复制它。或者它可能有.copy()方法,或者您可以使用copy模块。例如:

from copy import copy

# ...

bestsolution = copy(Solution)

copy.copy()浅层副本,意味着它会创建一个新的顶级对象,但会在其中放置对原始对象包含的相同对象的引用。如果这不起作用,请尝试copy.deepcopy(),它也会复制包含的对象及其包含的任何对象,等等。