Python 我为TSP编写了这段模拟退火代码,我整天都在尝试调试它,但出现了一些问题

Python 我为TSP编写了这段模拟退火代码,我整天都在尝试调试它,但出现了一些问题,python,traveling-salesman,simulated-annealing,Python,Traveling Salesman,Simulated Annealing,此代码假设要缩短初始巡更的距离:distan(initial_tour)random.random(): 当前\u最佳=新的\u解决方案 #跟踪找到的最佳解决方案 如果distan(当前最佳)

此代码假设要缩短初始巡更的距离:distan(initial_tour)我需要更改交换方法吗? 出了问题,模拟退火不起作用:

def prob(currentDistance,neighbourDistance,temp):

    if neighbourDistance < currentDistance:
       return 1.0

    else:
       return math.exp( (currentDistance - neighbourDistance) / temp)


def distan(solution):

    #gives the distance of solution


    listax, listay = [], []
    for i in range(len(solution)):

       listax.append(solution[i].x)
       listay.append(solution[i].y)

    dists = np.linalg.norm(np.vstack([np.diff(np.array(listax)), np.diff(np.array(listay))]), axis=0)
    cumsum_dist = np.cumsum(dists)

    return cumsum_dist[-1]


#simulated annealing

temp = 1000000

#creating initial tour

shuffle(greedys)

initial_tour=greedys


print (distan(initial_tour))

current_best = initial_tour

best = current_best

while(temp >1 ):

    #create new neighbour tour 

    new_solution= current_best 

    #Get a random positions in the neighbour tour

    tourPos1=random.randrange(0, len(dfar))
    tourPos2=random.randrange(0, len(dfar))

    tourCity1=new_solution[tourPos1]
    tourCity2=new_solution[tourPos2]

    #swapping
    new_solution[tourPos1]=tourCity2
    new_solution[tourPos2]=tourCity1

    #get distance of both current_best and its neighbour 

    currentDistance = distan(current_best)

    neighbourDistance = distan(new_solution)


    # decide if we should accept the neighbour
    # random.random() returns a number in [0,1)

    if prob(currentDistance,neighbourDistance,temp) > random.random():

        current_best = new_solution 

    # keep track of the best solution found  

    if distan(current_best) <  distan(best):

        best = current_best

    #Cool system

    temp = temp*0.99995


print(distan(best)) 
def prob(当前距离、相邻距离、温度):
如果相邻距离<当前距离:
返回1.0
其他:
返回math.exp((当前距离-相邻距离)/temp)
def蒸馏器(溶液):
#给出解的距离
listax,listay=[],[]
对于范围内的i(len(溶液)):
追加(解决方案[i].x)
追加(解决方案[i].y)
dists=np.linalg.norm(np.vstack([np.diff(np.array(listax)),np.diff(np.array(listay))),axis=0)
累积和分布=np.累积和(分布)
返回cumsum\u dist[-1]
#模拟退火
温度=1000000
#创建初始巡更
洗牌(格里迪)
初次旅行=格里迪
打印(distan(初始巡回)
当前\u最佳=初始\u巡回
最佳=当前最佳
而(温度>1):
#创建新邻居旅游
新的解决方案=当前的最佳解决方案
#在邻居巡更中获得随机位置
tourPos1=random.randrange(0,len(dfar))
tourPos2=random.randrange(0,len(dfar))
tourCity1=新的_解决方案[tourPos1]
tourCity2=新的解决方案[tourPos2]
#交换
新的_解决方案[tourPos1]=tourCity2
新的_解决方案[tourPos2]=tourCity1
#获取当前_best及其邻居的距离
当前距离=距离(当前最佳)
邻居距离=距离(新的_解决方案)
#决定我们是否接受邻居
#random.random()返回[0,1]中的数字
如果prob(currentDistance,NeigurDistance,temp)>random.random():
当前\u最佳=新的\u解决方案
#跟踪找到的最佳解决方案
如果distan(当前最佳)
您的问题出现在
循环的第一行,而
循环就是您编写代码的地方

new_solution= current_best 
这样做的目的是将对
current\u best
列表的引用放入
new\u solution
。这意味着当您更改
new\u solution
时,实际上您也在更改
current\u best
,这不是您的意图

问题可以通过将有问题的行替换为将列表复制到新列表中的行来解决,如下所示:

new_solution = list(current_best)

你能告诉我们出了什么问题吗?如果你有一个错误,请发表它。我会考虑使用不同的温度,可能是从1到0.0000001,而不是从1000000到1。现在看来,你的代码在接受恶化的解决方案时太慷慨了。加上@ MeeNess的评论:你应该考虑DIST的大小。与温度大小相比,温度差异很大。当距离变化的典型大小与温度大小相当时,您会看到接受度的急剧变化。问题可能是您不断降低温度。您是否考虑过使用更小的特定温度集,但在每个温度下重复多次(直到热化)?由于最初的温度很高,您可能会离开起点,陷入更糟糕的状态(?)。噢,我想我已经弄明白你的问题所在了!你所有的工作都在同一个列表上!你不是在复制列表,你只是在引用它。实际上,这意味着你正在接受每一个更改。尝试
new\u solution=list(current\u best)
,以便在更改列表之前复制一份。是的,它可以工作!!!谢谢!!