【问题标题】:How do I access this variable in my code?如何在我的代码中访问此变量?
【发布时间】:2017-12-14 16:24:02
【问题描述】:

这是我的模拟退火代码,用于解决旅行商问题。 cmets 应该描述正在发生的事情。出于某种原因,该算法会打印出它找到的最佳游览 LENGTH,而不是实际游览本身。如果我要添加一个

 print(solution) 

 if ap>=rd.random()

它打印的最后一次巡演每次都是最好的巡演。我该如何访问该旅游?最好不创建数组。


def 模拟退火(cityMat):

#generate a random tour
solution = genRandom(cityMat)

#get its length
solution_cost = getTourLength(solution, cityMat)

#set initial temperature
temperature = 1.0

#set limit to iterate to
limit = 100

#set final temperature
min_temperature = 0.00001

#set cooling rate
cooling_rate = 0.90

# variable for best solution
best_solution = solution
best_solution_cost = solution_cost



while temperature > min_temperature:      
    for i in range(1, limit + 1):  # use for loops when you can

        #generate neighbour tour
        neighbour = genNeighbour(solution)
        neighbour_cost = getTourLength(neighbour, cityMat)

        #get probability of accepting new tour
        probabilty_of_acceptance = acc_prob(
            solution_cost, neighbour_cost, temperature
        )
        best_solutions = []
        #####
        if neighbour_cost < solution_cost:
             best_solutions.append(neighbour)
             print(best_solutions) #could just print best_solution see the print below (and where the actual best solution is)
             best_solution = neighbour
             best_solution_cost = neighbour_cost
        #####

        # switch if random value greater than probability
        if probabilty_of_acceptance >= rd.random():
            solution = neighbour
            solution_cost = neighbour_cost

    #cool temperature
    temperature *= cooling_rate


return best_solution_cost, best_solution


[[16, 11, 13, 6, 25, 8, 14, 17, 15, 23, 21, 10, 22, 20, 19, 7, 12, 0, 3, 2, 5, 4, 9, 24, 1, 18]]
[[16, 11, 13, 6, 25, 8, 14, 17, 15, 23, 21, 10, 22, 20, 19, 12, 7, 0, 3, 2, 5, 4, 9, 24, 1, 18]]
[[16, 11, 13, 6, 25, 8, 14, 17, 23, 15, 21, 10, 22, 20, 19, 12, 7, 0, 3, 2, 5, 4, 24, 9, 1, 18]]
[[16, 11, 6, 14, 8, 25, 13, 17, 23, 10, 15, 22, 21, 12, 20, 7, 0, 19, 4, 5, 24, 9, 3, 2, 1, 18]]
[[14, 11, 8, 16, 6, 25, 13, 10, 12, 15, 17, 23, 5, 20, 22, 4, 0, 21, 19, 24, 9, 7, 2, 18, 1, 3]]
[[14, 11, 8, 16, 6, 25, 13, 10, 12, 15, 17, 23, 20, 5, 22, 4, 21, 0, 19, 24, 9, 7, 2, 18, 1, 3]]
[[14, 11, 8, 6, 25, 16, 13, 10, 12, 15, 17, 23, 22, 20, 5, 4, 21, 0, 19, 24, 9, 7, 2, 1, 18, 3]]
[[15, 25, 6, 10, 21, 12, 4, 22, 7, 14, 23, 13, 11, 8, 16, 5, 2, 0, 3, 24, 9, 1, 18, 19, 20, 17]]
[[7, 1, 0, 21, 5, 23, 25, 2, 15, 16, 12, 22, 6, 20, 19, 24, 3, 10, 9, 4, 8, 17, 18, 13, 14, 11]]
[[7, 1, 0, 5, 21, 23, 25, 2, 15, 16, 12, 22, 24, 6, 20, 19, 3, 10, 9, 4, 17, 8, 13, 18, 14, 11]]
[[7, 1, 0, 5, 21, 23, 25, 2, 15, 16, 12, 22, 24, 6, 20, 19, 3, 10, 9, 4, 8, 17, 13, 18, 14, 11]] #THIS IS THE BEST SOLUTION
(1980, [25, 2, 10, 22, 20, 6, 7, 24, 16, 8, 15, 1, 14, 23, 21, 5, 3, 0, 12, 19, 4, 11, 13, 17, 18, 9]) 

def getTourLength(tour, cityMat):
    cityLen = len(tour)
    tourLength = []
    for k in range(0,cityLen-1):
        tourLength.append(cityMat[tour[k]][tour[k+1]])
    tourLength.append(cityMat[tour[cityLen-1]][tour[0]])
    cost = sum(tourLength)
    return cost 

def genNeighbour(tour):
    ranSwap = rd.randint(0,len(tour)-2)
    tour[ranSwap], tour[ranSwap+1] = tour[ranSwap+1], tour[ranSwap]
    return tour 

【问题讨论】:

  • 以后使用更具描述性的变量名。跟踪 ap, rn, l, ln, alpha, T, T_min, n, i 是一场噩梦。并且不要将 random 模块缩短为 rd 看在上帝的份上!无论如何,我不明白您认为如何在不创建列表的情况下存储数据?你为什么不想这样做?
  • 我想我可以将它存储为临时变量或其他东西。你知道我可以用一个列表来做吗?
  • 已编辑我的代码以使其更合理。我想避免这种情况以降低空间复杂度。

标签: python traveling-salesman simulated-annealing


【解决方案1】:

我使您的代码更具可读性。你真的应该看看PEP8,因为你打破了大多数公认的风格形式。这就是您想要的,一种存储最佳解决方案的方法吗?你不是很清楚...

import random

def simulate_annealing(city_matrix):

    #generate a random tour
    solution = generate_random(city_matrix)

    #get its length
    solution_cost = tour_length(solution, city_matrix)

    #set initial temperature
    temperature = 1.0

    #set limit to iterate to
    limit = 100

    #set final temperature
    min_temperature = 0.00001

    #set cooling rate
    cooling_rate = 0.90

    # variable for best solution
    best_solution = solution
    best_solution_cost = solution_cost

    while temperature > min_temperature:      
        for i in range(1, limit + 1):  # use for loops when you can

            #generate neighbour tour
            neighbour = generate_neighbour(solution)
            neighbour_cost = tour_length(neighbour, city_matrix)

            #get probability of accepting new tour
            probabilty_of_acceptance = acceptance_probability(
                solution_cost, neighbour_cost, temperature
            )

            #####
            if neighbour_cost < solution_cost:  # I assume we can compare these
                 best_solution = neighbour
                 best_solution_cost = neighbour_cost
            #####

            # switch if random value greater than probability
            if probability_of_acceptance >= random.random():
                solution = neighbour
                solution_cost = neighbour_cost

        #cool temperature
        temperature *= cooling_rate

    # change this how you see fit (print or whatever)
    return best_solution_cost, best_solution

编辑:是的,我明白了。这是一个经典的蟒蛇gotchya。您正在就地编辑当前数组,因此每次生成新邻居时它都会更改。你需要像这样复制旅游。

 def genNeighbour(tour):
    tour_copy = tour.copy()  # or tour[:]
    ranSwap = rd.randint(0,len(tour)-2)
    tour_copy[ranSwap], tour_copy[ranSwap+1] = tour[ranSwap+1], tour[ranSwap]
    return tour_copy

【讨论】:

  • 我遇到的问题是,尽管 best_solution_cost 是最好的旅游成本,但生产的 best_solution 实际上并不是最好的旅游。我不知道为什么会这样。我已使用您改进的代码使其更具可读性,但 best_solution 实际上不是最好的问题仍然存在。如果我要在其 if 语句中 print(best_solution),最后一个 print 是 best_solution,但返回的是 ISN'T。
  • 嗯,这几乎肯定是您的tour_length 函数的问题。 .我想你应该去检查一下。您在这里提出的逻辑非常合理。你用什么衡量标准说best_solution 实际上不是最好的? best_solution必须最低best_solution_cost
  • 当 tour_length 函数决定了 best_solution 时,怎么会出现问题?当我打印 best_solution 时,最终打印与返回的不同。当我检查最终打印的行程长度时,它与 best_solution_cost 相同。由于某种原因,返回的内容与 best_solution 的最终打印结果不同。它也没有出现在任何印刷品中。如果可能的话,我想将最终打印分配给一个变量,然后存储它,但这可能是不可能的。
  • 好吧...最后的solution 不一定是最好的。这就是优化算法的本质。 solution 在遇到更好的neighbour 时不会改进的可能性是有限的,但如果成本更低,neighbour 仍然可以替代best_solutionbest_solution总是拥有最低的solution_cost。我认为您需要离开并考虑一下算法在做什么。
  • 不知道是不是这个原因。我的算法产生的结果更差/与仅生成随机游览结果相似 - 你确定我正确地存储了 best_solution 吗?我创建了一个数组best_solutions = []并在if语句中做了best_solutions.append(best_solution),得到的数组只是一个解决方案数组
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
相关资源
最近更新 更多