我正在尝试实现模拟退火(SA(算法,以解决python中旅行推销员问题(TSP(的一个随机实例。在我的代码中,我有一个函数来计算旅行的总经度,给出一个包含路线和距离矩阵的列表。当我运行我的代码时,我有以下与此函数相关的错误。
UnboundLocalError:在分配之前引用了本地变量"t">
我的代码如下:
N=4
D=np.zeros([N,N])
random.seed(13)
for i in range(N):
for j in range(N):
D[i,j]=random.randint(15,100)
for i in range(N):
D[i,i]=10000
print("")
print("- Number of cities=",N)
print("")
print("- =")
print("- Distance matrix")
print(D)
#GENERATE ROUTES FUNCTION:
def generar_tour(N):
ruta=range(N)
ruta_obtenida=random.sample(ruta,len(ruta))
return ruta_obtenida
#Function for calculating the length of the route
def distancia_tour(ejemplo,D):
longitud=0
for t in range(len(ejemplo)-1):
longitud=longitud+D[ejemplo[t],ejemplo[t+1]]
longitud=longitud+D[ejemplo[t+1],ejemplo[0]]
return longitud
#SIMULATED ANNEALING ALGORITHM
T_inicial=5000
tour_inicial=generar_tour(N)
distancia_inicial=distancia_tour(tour_inicial,D)
print("TOUR INICIAL=",tour_inicial,"| LONGITUD TOUR=",distancia_tour(tour_inicial,D))
tour_actual=[]
tour_vecino=[]
distancia_vecino=0
distancias=[]
iteracion=[]
IT_max=1000
iterador=1
contar=1
while T_inicial>10**(-5):
while iterador>IT_max:
tour_vecino=generar_tour(N)
distancia_vecino=distancia_tour(tour_vecino,D)
if distancia_vecino-distancia_inicial<0:
tour_actual=tour_vecino
else:
if random.random()<math.exp(-(distancia_vecino-distancia_inicial)/T_inicial):
tour_actual=tour_vecino
iterador=iterador+1
T_inicial=0.9999*T_inicial
print("RUTA=",tour_actual,"|","DISTANCIA TOTAL=",distancia_tour(tour_actual,D),"|","TEMPERATURA ACTUAL=",T_inicial)
distancias.append(distancia_tour(tour_actual,D))
iteracion.append(contar)
contar=contar+1
plt.plot(contar,distancias,'b')
plt.show()
我不得不在谷歌上搜索,但使用最常见的解决方案"全局"和其他解决方案是行不通的。有什么想法吗?我确信这不是一个难题,只是我看不出来。有什么提示吗?提前感谢和智利的问候。
Samuel Muldoon在他的回答中说,这个错误意味着你在设置其值之前试图使用t
。代码中的挑战在于,很难看出这是如何发生的。看起来你总是在distancia_tour
的for
循环中设置t
,那么怎么可能不设置呢?
事实证明,由于代码中的错误,您向distancia_tour
函数传递了一个空列表。空列表的长度为0,因此for
循环有效:
for t in range(-1):
...
range(-1)
返回一个空列表,因此在for
循环中没有要迭代的值。t
从未给定值,当for
循环后的下一行引用t
时,会出现错误。
它得到空列表的原因是,您将tour_actual
初始化为空列表,然后由于while
语句中的错误而不更改其值。您有while iterador>IT_max:
,它从不执行,因为iterador
小于IT_max
。你可能打算测试iterador < IT_max
。
这意味着当计算机以前从未见过t
时,您尝试读取t
。假设你写了这样的东西:
x = t*99 + 3
但CCD_ 20在节目的早些时候从未出现回答。除非计算机知道t
是什么,否则它无法将t
乘以99。在给它分配任何东西之前,你试图用t
做一些事情。
以下是我的建议(有效(:!(:在函数和要迭代的变量中使用if子句时-->脚本的所有块都将属于if子句,包括初始化var=0及其最终值(下面的情况1(-->或者初始化和最终值将在if子句之外(下面的情况2(-->但在任何情况下,除非出现错误,否则它们中的一个都不会出现在if子句中,即:;UnboundLocalError:在赋值之前引用的局部变量"variable"(">
案例1:
def dist_hamming(A, B):
if len(A) == len(B):
dist = 0 #My variable "dist" is inside the if-clause
for i in range(len(A)):
if A[i] != B[i]:
dist += 1
distance = dist #Again my variable is inside the if-clause
return distance
else:
print("Please ensure the lenghts of the two sequence entered are identical !")
案例2:
def dist_hamming(A, B):
dist = 0 #My variable "dist" is outside the if-clause
if len(A) == len(B):
for i in range(len(A)):
if A[i] != B[i]:
dist += 1
else:
print("Please ensure the lenghts of the two sequence entered are identical !")
distance = dist #Again, my variable is outside the if-clause
return distance