【问题标题】:Simulated Annealing in Python, Variables in While loop?Python中的模拟退火,While循环中的变量?
【发布时间】:2016-01-12 20:46:00
【问题描述】:

在成功编写了遗传算法后,我现在正在编写一个模拟退火程序,用于与 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

【问题讨论】:

    标签: python while-loop simulated-annealing


    【解决方案1】:

    问题不在于“将变量传递回 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(),它还会复制包含的对象及其包含的任何对象,等等。

    【讨论】:

    • 既然我们不知道Solution是什么对象,那么copy.deepcopy()不是更好的选择吗?
    • 嗯,可能。通常浅拷贝工作得很好,因为它们更快并且使用更少的内存,我从那里开始。不过,在答案中添加了一些关于 deepcopy 的内容。
    • 这是有道理的。解决方案对象是一个类对象,它将实际上是列表的列表组合在一起。如果我将其定义为一个函数,那么会实例化解决方案来克服这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 2017-04-16
    • 2010-12-04
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-11-02
    相关资源
    最近更新 更多