2

This code suppose to reduce the distance of initial tour: distan(initial_tour) < distan(best) . Can you help me plz? I 've been trying all day now. Do I need to change my swapping method? Something goes wrong and the simulated annealing does'not work:

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)) 
van boeren
  • 169
  • 2
  • 2
  • 9
  • Can you tell us what goes wrong? If you're getting an error, please post it. – Blue Star Oct 16 '16 at 23:44
  • Thanks for your reply. I am not getting an error, I have an initial tour of the cities which is the output of the greedy algorithm. Then I use this initial tour as an input of simulated annealing algorithm in order to approach the optimal solution. Simulated annealing must give me a tour ( the variable=best) < initial tour. But this is not happening. For example my initial tour is 60 and the new tour (variable=best) is 70. Maybe my swapping method is too naive and therefore is not possible to approach good solutions. – van boeren Oct 16 '16 at 23:48
  • 1
    I would consider using different temperatures, perhaps from 1 to 0.0000001 instead of from 1000000 to 1. As it stands now, it looks like your code is too generous in accepting worsening solutions. – Blue Star Oct 16 '16 at 23:53
  • still : total length of initial tour: 45173.277736 total length of best tour : 49254.0557391 – van boeren Oct 17 '16 at 00:01
  • 1
    Adding to the comment of @Meerness: you should consider the magnitude of distance differences compared to the magnitude of temperature. You will see drastic changes in acceptance when the typical size of distance changes is comparable in magnitude to the temperature. It's possible that the issue is that you're constantly decreasing the temperature. Have you considered using a smaller, specific set of temperatures, but spending many iterations (until thermalization) at each temperature? Since initially the temperature is high, you can get away from the start and get stuck in a worse state (?). – Andras Deak -- Слава Україні Oct 17 '16 at 00:08
  • Another thing I notice is that your distance function is strange and non-intuitive. What sort of distance are you trying to calculate? Perhaps a simple Euclidian distance calculation would serve you better. – Blue Star Oct 17 '16 at 00:14
  • I did it and still getting bad solutions with many crosses. :( – van boeren Oct 17 '16 at 00:14
  • @Meerness this is Euclidian distance – van boeren Oct 17 '16 at 00:15
  • 1
    Oh, I think I've figured out what your problem is! All of your work is on the same list! You aren't copying the list, you're just referencing it. In effect, that means you're accepting every change. Try `new_solution = list(current_best)` in order to make a copy of the list before you change it. – Blue Star Oct 17 '16 at 00:34
  • @Meerness nice catch, I was too pre-occupied with the theoretical aspect that I didn't pause for a second to wonder about the python part:) – Andras Deak -- Слава Україні Oct 17 '16 at 00:42
  • 1
    YES IT WORKS!!! Thanks!! – van boeren Oct 17 '16 at 00:44
  • still there is a chance to be a cross, but it works 99% perfect! – van boeren Oct 17 '16 at 00:46
  • I want the last city to be the first city. But this doesn't happen as I want. Do you have any suggestions? @Meerness – van boeren Oct 17 '16 at 01:09
  • I'm not sure you mean. Can you elaborate? (Also, I'm going to post the solution to your original question as a solution so that people don't come here to try to solve a problem that's been solved.) – Blue Star Oct 17 '16 at 01:30
  • Oh, you want the traveling salesman to finish where he started? I suggest adding the first element in the list to the end of it before calculating the distance. So maybe instead of writing `distan(current_best)` you could write `distan(current_best + [current_best[0]])` or something like that. – Blue Star Oct 17 '16 at 01:40
  • thanks but in which point do I append the first city to the list? So the last city will be the first city. – van boeren Oct 17 '16 at 01:50
  • can you give me your facebook or email address to send you the full code to see the results? everything is good but there are still some crosses and wrong lines. And I used a dataset and I am way off from the optimal solution. – van boeren Oct 17 '16 at 01:57

1 Answers1

0

Your problem is in the first line of your while loop, where you write

new_solution= current_best 

What this does is puts a reference to the current_best list into new_solution. This means that when you change new_solution, you're actually changing current_best as well, which was not your intention.

The problem could be solved by replacing the problematic line with one that copies the list into a new list, like so:

new_solution = list(current_best)
Blue Star
  • 1,932
  • 1
  • 10
  • 11