0

I'm trying to solve Traveling Salesman problem using Differential Evolution. For example, if I have vectors:

[1, 4, 0, 3, 2, 5], [1, 5, 2, 0, 3, 5], [4, 2, 0, 5, 1, 3]

how can I make crossover and mutation? I saw something like a+Fx(b-c), but I have no idea how to use this.

Gomo55
  • 21
  • 2
  • 1
    [Artificial Intelligence Stack Exchange](https://ai.stackexchange.com/) is another site where you can ask theoretical questions related to any type of evolutionary computation. If you decide to ask this question there, please, delete it from here, so that we avoid cross-posting. Moreover, if you decide to ask it there, I suggest that you focus either on the cross-over or mutation (and not both) in the same post. Ask a separate question for the cross-over. Moreover, when you say "I saw something like ...", please, provide the link to the article or the place where you saw such a thing. – nbro Jan 16 '21 at 15:24

2 Answers2

0

I ran into this question when looking for papers on solving the TSP problem using evolutionary computing. I have been working on a similar project and can provide a modified version of my written code.

For mutation, we can swap two indices in a vector. I assume that each vector represents an order of nodes you will visit.

def swap(lst):

        n = len(lst)
        x = random.randint(0, n)
        y = random.randint(0, n)
        
        # store values to be swapped
        old_x = lst[x]
        old_y = lst[y]

        # do swap
        lst[y] = old_x
        lst[x] = old_y

    return lst

For the case of crossover in respect to the TSP problem, we would like to keep the general ordering of values in our permutations (we want a crossover with a positional bias). By doing so, we will preserve good paths in good permutations. For this reason, I believe single-point crossover is the best option.

def singlePoint(parent1, parent2):

        point = random.randint(1, len(parent1)-2)

        def helper(v1, v2):
            # this is a helper function to save with code duplication

            points = [i1.getPoint(i) for i in range(0, point)]
            
            # add values from right of crossover point in v2
            # that are not already in points
            for i in range(point, len(v2)):
                pt = v2[i]
                if pt not in points:
                    points.append(pt)

            # add values from head of v2 which are not in points
            # this ensures all values are in the vector.
            for i in range(0, point):
                pt = v2[i]
                if pt not in points:
                    points.append(pt)

            return points
        
        # notice how I swap parent1 and parent2 on the second call
        offspring_1 = helper(parent1, parent2)
        offspring_2 = helper(parent2, parent1)

        return offspring_1, offspring_2

I hope this helps! Even if your project is done, this could come in handy GA's are great ways to solve optimization problems.

Joshua Reisbord
  • 111
  • 2
  • 7
  • In `helper()`, I notice `v1` to be unused. And what is `getPoint(i)`? – greybeard Apr 10 '22 at 22:52
  • (You could use `for pt in v2[point:]:` and `for pt in v2[:point]:` there. If `i1.getPoint(i) for…` was `v1[:point]`, you could just use `if pt in v1[point:]: points.append(pt)`.) – greybeard Apr 10 '22 at 23:03
-1

if F=0.6, a=[1, 4, 0, 3, 2, 5], b=[1, 5, 2, 0, 3, 5], c=[4, 2, 0, 5, 1, 3] then a+Fx(b-c)=[-0.8, 5.8, 1.2, 0, 3.2, 6.2] then change the smallest number in the array to 0, change the second smallest number in the array to 1, and so on. so it return [0, 4, 2, 1, 3, 5]. This method is inefficient when used to solve the jsp problems.