I am having some trouble with variables being set as the same when they shouldn't be and I can't figure out why they're doing it. In my case, LCT and MCT are being set as the last route generated in the function, but I only have them being set when the route is less than or more than the least cost or most cost, respectively. Basically, I'm creating a pseudo-random list of the integers from 0-13 as city labels, and finding the distance between them using an i-by-j array lookup where the value indicates the distance when traveled from city i to city j. This is part of my TSP project. Here's some code for reference:
import random
def distance(x1, y1, x2, y2):
"""
Finds the distance between two points with coordinates (x1, y1) and (x2, y2)
:param x1: x-coordinate of first point
:type x1: float or int
:param y1: y-coordinate of first point
:type y1: float or int
:param x2: x-coordinate of second point
:type x2: float or int
:param y2: y-coordinate of second point
:type y2: float or int
:return: distance between two points
:rtype: float
"""
return (((x2-x1)**2) + ((y2-y1)**2)) ** 0.5
def shuffle(idxs):
"""
Performs random swaps n times with random seeded generator
:param idxs: Set of items to choose from
:type idxs: list, tuple, or dict
:return: modified idxs
:rtype modified idxs: type(idxs)
"""
n = 32
for k in range(n):
random.seed()
a, b = random.randint(0, 13), random.randint(0, 13)
swap(idxs, a, b)
# print(idxs)
return idxs
def swap(mylist, a, b):
"""
Swaps two values
:param mylist: order of things to choose from
:type mylist: list, tuple, or dict
:param a: first index
:type a: list/tuple: int; dict: key
:param b: second index
:type b: list/tuple: int; dict: key
:return: none; edits items in place
"""
temp = mylist[a]
mylist[a] = mylist[b]
mylist[b] = temp
mat = [[0.430796749, 0.660341257],
[0.869607109, 0.145710154],
[0.272249997, 0.281035268],
[0.310050105, 0.717362826],
[0.847481151, 0.505130257],
[0.054921944, 0.597324847],
[0.565507064, 0.578311901],
[0.578311901, 0.636552793],
[0.170565332, 0.160881561],
[0.800726237, 0.384045138],
[0.622627218, 0.957622127],
[0.608021461, 0.736718151],
[0.628737267, 0.622146623],
[0.665929436, 0.720342005]]
distances = [[distance(x1=mat[i][0], y1=mat[i][1],
x2=mat[j][0], y2=mat[j][1]) for j in range(14)] for i in range(14)]
route = [i for i in range(14)]
bigN = 1000
LC = 100
MC = 0
for j in range(bigN):
this_dist = 0
route = shuffle(route)
# print('Route:', route)
# Get the distance for the route
for stop in range(len(route)):
if stop != len(route) - 1: # if its not the last node
this_dist += distances[route[stop]][route[stop + 1]]
else: # Add cost from last item to first item
this_dist += distances[route[stop]][route[0]]
# print('Distance:', this_dist)
# Update min/max
if this_dist < LC:
LC = this_dist
LCT = route
print('New low:', LCT, 'Distance:', LC)
elif this_dist > MC:
MC = this_dist
MCT = route
print('New high:', MCT, 'Distance:', MC)
print('Last route:', route, 'Last distance:', this_dist)
# Output
print('Least cost:', LC)
print('Least cost trip:', LCT)
print('Most cost:', MC)
print('Most cost trip:', MCT)
If you just copy and paste this into an IDE and run it, you will see what I mean. LCT and MCT are being set as the last route generated (even though it's not the least/most cost trip), when I only have them being changed when the current route is shorter/longer than the current least/most cost. Why is this happening and what can I do to have it properly set as the LCT/MCT? I am very confused and sorry if this is a long post, but I can't figure this out. I'm using Python 3.7, if that helps any. Edit: problem clarification.
I expect LCT/MCT to at least be different because they would have different routes and different distances associated with them. My issue is that the variables are being set as the very last route generated, regardless of if it's actually shorter/longer than the actual shortest/longest route. Each time the current route is shorter/longer than the actual shortest/longest route, I have it print out the new route and the new shortest distance. LCT/MCT should be set as the last respective one printed out.
Last edit: jasonharper's solution in the comments worked (sorry if I butchered the username, you can't see them in edit mode and I don't have enough rep to post comments). I just had to add [:] to the end of routes when I copied them to LCT/MCT. Thanks!
答案 0 :(得分:0)
Basically route is mutable and it is changed each time. When you set LCT/MCT it is a pointer to route. You can use the suggestion from @jasonharper and update the code as follows:
# Update min/max
if this_dist < LC:
LC = this_dist
LCT = route[:]
print('New low:', LCT, 'Distance:', LC)
elif this_dist > MC:
MC = this_dist
MCT = route[:]
print('New high:', MCT, 'Distance:', MC)