In [319]:
import numpy as np
from scipy import spatial

In [356]:
def evaluate_tour_len(x,d):
    '''
    x: solution
    d: DxD matrix of Euclidean distance
    '''
    L = 0
    for i in range(len(x)-1):
        # print(x[i],x[i+1])
        L += d[x[i],x[i+1]]
        # print(d[x[i],x[i+1]],L)
    L += d[len(x)-1,0]
    # print(d[x[len(x)-1],x[0]],L)
    return L

In [321]:
x = np.array([2,3,1,0])
y = np.matrix([[5,5,6,6],
             [7,7,7,7],
             [1,2,3,4],
             [8,8,8,8]])
evaluate_tour_len(x,y)


Out[321]:
27

In [322]:
def order_crossover(xa,xb):
    xa = np.copy(xa)
    xb = np.copy(xb)
    D = len(xa)
    r = np.arange(D)
    np.random.shuffle(r)
    if r[0]<r[1]:
        c1 = r[0]
        c2 = r[1]
    else:
        c1 = r[1]
        c2 = r[0]
    u = xa
    #print(c1,c2)
    for j in range(c1,c2+1):
        h = np.where(u==xb[j])[0][0]
        l = h + 1
        while h!=c2:
            # print(h,l)
            if h == D :
                h = 0
            if l == D :
                l = 0
            u[h] = u [l]
            h += 1
            l += 1
        # print(u)
    for j in range(c1,c2+1):
        u[j] = xb[j]  
    return u

D = 10 a = np.arange(D) np.random.shuffle(a) b = np.arange(D) np.random.shuffle(b) u = order_crossover(a,b) print(a,b,u)


In [323]:
def inversion_mutation(vector,probability):
    '''
    a kind of mutation machanism for permutation problem
    flip
    '''
    if np.random.rand() > probability:  
        D = len(vector)
        r = np.arange(D)
        np.random.shuffle(r)
        [m1,m2] = sorted([r[0],r[1]])
        # print(m1,m2)
        vector[m1:(m2+1)] = np.flip(vector[m1:(m2+1)],0)
    return vector

In [324]:
def random_init(mu,P,D, evaluate_func,d):
    '''
    initialize and evaluate the population
    mu: number of the individuals
    P: the list for the population and value
    D: dimension
    '''
    x = np.arange(D)
    for i in range(mu):
        np.random.shuffle(x)
        vector = np.copy(x)
        #print(evaluate_func(vector,d))
        P.append((vector,evaluate_func(vector,d)))
    return P

In [325]:
def get_distance_matrix(TSP_data):
    '''
    get the distance matrix
    '''
    x = scipy.spatial.distance.pdist(TSP_data,'euclidean')
    d = scipy.spatial.distance.squareform(x)
    return d

In [364]:
def genetic_algorithm(TSP_data):
    '''
    converge condition: bsf not change for 20 generations
    '''
    D = len(TSP_data)
    pm = 1/D
    n = 0
    mu = D
    t = 0
    lambda_ = 2*mu
    d = get_distance_matrix(TSP_data)
    P = list()
    random_init(mu,P,D,evaluate_tour_len,d)
    x_bsf = sorted(P,key=lambda x:x[1])[0]
    count_no_change = 0
    while count_no_change<200:
        Q = list()
        updated = False
        for i in range(lambda_):
            # Step1 Mating Selection
            r = np.arange(len(P))
            np.random.shuffle(r)
            selected = r[:2]
            # Step2: Variation operator : Order Crossover
            u = order_crossover(P[selected[0]][0],P[selected[1]][0])
            # Step3: Variation operator2: inversion_mutation
            u = inversion_mutation(u,pm)
            # Step4: Evaluate
            new_value = evaluate_tour_len(u,d)
            n += 1
            Q.append((u,new_value))
            # Step5: Update bsf solution
            if new_value <x_bsf[1]:
                updated = True
                x_bsf=(u,new_value)
                print(x_bsf)
        # Step6: Environment Selection
        R = P + Q
        sort_result = sorted(R,key=lambda x:x[1])
        P = sort_result[:int(len(R)/2)]
        t += 1
        if updated == True:
            count_no_change = 0
        else:
            count_no_change += 1
    return (t,n,x_bsf)

In [368]:
def main():
    data = list()
    # dj38.tsp
    with open("wi29.tsp") as tspdata:
        for line in tspdata:
            linedata = line.split(' ')
            if linedata[0].isdigit():
                data.append((float(linedata[1]),float(linedata[2])))
                #print(data[-1])
    #print(d)
    x = genetic_algorithm(data)
    print(x)
    return

In [370]:
main()


(array([27,  1,  0,  9,  6,  5,  4,  2, 23, 26, 15, 17, 12, 25,  8, 21, 20,
        3, 18, 22, 24, 10, 14, 11, 19,  7, 13, 28, 16]), 96851.065119185194)
(array([24, 21,  6,  4,  1,  9, 16, 28, 20, 22, 18,  2, 23, 17, 12, 25, 14,
       11, 10,  7,  5, 27, 15,  8,  0, 13, 26, 19,  3]), 96562.498759647759)
(array([20, 18, 25, 14, 10, 24,  6,  5,  4,  2, 21,  8,  1,  0,  9, 27, 17,
       23, 26, 22, 19, 12, 11,  3,  7, 16, 28, 13, 15]), 86455.726487085951)
(array([15, 25, 20, 18, 24, 14, 10,  5,  6,  2, 21,  8,  1,  0,  9, 27, 17,
       23, 26, 22, 19, 12, 11,  3,  7, 16, 28, 13,  4]), 81584.585096167779)
(array([ 2,  8,  0,  9,  1,  5,  3, 23, 21, 26, 13, 15, 19, 12, 27, 17, 24,
       11,  7, 10,  6,  4, 16, 22, 28, 25, 20, 18, 14]), 78488.097212564011)
(array([13, 17,  6,  2,  3, 12,  0,  1,  8, 21, 20, 18, 26, 24, 25, 19, 16,
       22,  4,  7, 10,  9, 27, 28, 14, 11, 15, 23,  5]), 75374.515067163666)
(array([18, 20, 15, 24, 14, 10,  5,  6,  2,  4, 13, 28, 22, 16,  7,  3, 11,
       12, 19, 26, 23, 17, 27,  9,  0,  1,  8, 25, 21]), 74059.860890684227)
(array([ 2,  5,  4,  6, 12, 20, 13,  9, 10,  1,  0, 22, 11,  8, 14, 27, 19,
       15, 26, 24, 23, 17,  3,  7, 16, 28, 21, 25, 18]), 71348.975526727576)
(array([ 2,  3,  5,  1,  9,  0,  4,  7, 27, 19, 28, 22, 16,  6, 26, 24, 13,
       15, 25, 18, 20, 21, 23, 12, 11,  8, 17, 14, 10]), 70111.999321805502)
(array([ 0,  1,  5,  3,  4,  7, 12, 11, 24, 27, 17, 23, 15, 26, 22, 28, 25,
       20, 14, 13,  8,  2,  6,  9, 10, 16, 18, 21, 19]), 56493.286869981304)
(array([15, 26, 25, 27, 17, 19, 18, 22, 28, 21, 20, 24, 23, 16, 12,  7,  3,
       10, 14, 13,  8,  2,  6,  9, 11,  5,  1,  0,  4]), 53341.474579307513)
(array([17, 14,  9, 10,  1,  0,  5,  4,  3,  7, 13, 11,  6,  2,  8, 19, 16,
       23, 24, 25, 26, 15, 20, 18, 28, 22, 27, 21, 12]), 52483.849148777372)
(array([17, 14,  9, 10,  1,  0,  5,  4,  3,  7,  2,  6, 11, 13,  8, 19, 16,
       23, 24, 25, 26, 15, 20, 18, 28, 22, 27, 21, 12]), 52160.756806238016)
(array([ 1,  0,  5,  4,  3,  7,  2, 13, 11,  6,  8, 27, 22, 28, 16, 19, 23,
       24, 25, 26, 15, 20, 18, 21, 12, 17, 14,  9, 10]), 51580.056878597359)
(array([17, 14,  1,  0,  5,  4,  3,  7, 11, 19, 23, 24, 25, 26, 15, 20, 28,
       22, 27, 21, 18, 16, 10,  9,  6,  2,  8, 13, 12]), 51461.316504800881)
(array([ 4,  3,  7,  5,  1,  0, 10,  9,  2,  6, 16, 13,  8, 11, 12, 19, 17,
       14, 18, 27, 23, 24, 25, 26, 15, 20, 28, 22, 21]), 51171.599876452456)
(array([ 1,  0,  5,  4,  3,  7, 13, 11,  2,  6,  8, 27, 22, 28, 16, 19, 23,
       24, 25, 26, 15, 20, 18, 21, 12, 17, 14,  9, 10]), 50758.901776437546)
(array([17, 18, 13, 16, 27, 20, 26, 15, 25, 24, 23, 19, 28, 22, 21, 11,  7,
        4,  0,  1,  5,  9, 10,  3,  6, 12, 14,  8,  2]), 49763.450354313733)
(array([12, 14, 28, 22, 21, 18, 20, 27, 17, 13, 15, 26, 25, 24, 16, 19, 23,
        8,  2,  6, 11,  9, 10,  1,  0,  5,  4,  3,  7]), 48469.125994676157)
(array([23, 27, 19, 24, 26, 15, 22, 28, 21, 20, 25, 18, 16, 13,  8,  4,  0,
        1,  5, 11, 10,  9, 14, 17, 12,  6,  7,  3,  2]), 48232.931686275297)
(array([19, 16, 27, 23, 24, 25, 26, 15, 20, 28, 22, 21, 13, 17, 18, 14, 12,
       11,  8,  4,  7,  3,  9, 10,  6,  2,  5,  0,  1]), 47891.176244298418)
(array([22, 27, 28, 19, 23, 24, 25, 20, 18, 21, 17, 26, 15, 16, 11,  9, 10,
        1,  0,  5,  4,  3,  8,  6,  2,  7, 12, 14, 13]), 47280.199343315151)
(array([27, 25, 24, 16, 19, 23, 26, 15, 20, 28, 22, 21, 13, 17, 18, 14, 12,
        9, 10,  7,  3,  4,  5,  0,  1, 11,  2,  6,  8]), 45751.321345361714)
(array([16, 20, 28, 22, 19, 23, 24, 25, 26, 15, 13, 27, 18, 21, 17, 14, 12,
        8,  2,  6, 11,  9, 10,  1,  0,  5,  4,  3,  7]), 43188.780187948112)
(array([17, 13, 19, 25, 26, 15, 23, 24, 27, 28, 16,  8,  2,  6, 11,  9, 10,
        1,  0,  5,  4,  3,  7, 12, 14, 18, 21, 22, 20]), 42957.724091712887)
(array([13, 19, 25, 26, 15, 23, 24, 27, 17, 20, 22, 21, 18, 14, 12,  7,  3,
        4,  5,  0,  1, 10,  9, 11,  6,  2,  8, 16, 28]), 42837.709786525738)
(array([ 7,  3,  4,  5,  0,  1, 10,  9, 11,  6,  2,  8, 12, 14, 18, 21, 22,
       17, 16, 20, 27, 28, 13, 15, 25, 24, 26, 23, 19]), 40359.13458499351)
(array([ 7,  3,  4,  1,  0,  5, 10,  9, 11,  6,  2,  8, 12, 14, 18, 21, 22,
       17, 16, 20, 27, 28, 13, 15, 26, 23, 19, 25, 24]), 40116.679279211901)
(array([11,  9, 10,  1,  0,  5,  4,  3,  2,  6,  7,  8, 12, 14, 18, 21, 22,
       17, 16, 20, 27, 28, 13, 15, 19, 23, 26, 24, 25]), 39371.938591120277)
(array([11,  9, 10,  1,  0,  5,  4,  3,  6,  2,  7,  8, 12, 14, 18, 21, 22,
       17, 16, 20, 27, 28, 25, 24, 26, 23, 19, 15, 13]), 38787.056128892415)
(array([23, 24, 19, 25, 26, 15, 13, 16, 22, 20, 28, 27, 18, 21, 17, 14, 12,
        8,  2,  6, 11,  9, 10,  7,  3,  4,  5,  0,  1]), 38690.195379242599)
(array([ 1,  0,  5,  4,  3,  7, 10,  9, 11,  6,  2,  8, 12, 14, 18, 21, 22,
       17, 16, 20, 27, 28, 19, 13, 15, 23, 26, 24, 25]), 37845.854934047798)
(array([ 1,  0,  5,  4,  3,  7, 10,  9, 11,  6,  2,  8, 12, 14, 18, 21, 22,
       17, 16, 20, 13, 28, 27, 19, 25, 24, 26, 23, 15]), 37687.334817100927)
(array([ 6,  2,  8, 11,  9, 10,  1,  0,  5,  4,  3,  7, 12, 14, 18, 21, 22,
       28, 27, 20, 16, 17, 13, 19, 25, 24, 26, 23, 15]), 37412.640047007379)
(array([ 1,  0,  5,  4,  3,  7, 10,  9, 11,  6,  2,  8, 12, 13, 14, 18, 21,
       22, 17, 16, 20, 27, 28, 19, 25, 24, 26, 23, 15]), 35899.068910492046)
(array([11,  9, 10,  1,  0,  5,  4,  3,  7,  6,  2,  8, 12, 14, 18, 17, 22,
       21, 28, 27, 20, 16, 13, 19, 25, 24, 26, 23, 15]), 35671.932903718858)
(array([ 1,  0,  5,  4, 10,  9, 11,  7,  3,  6,  2,  8, 12, 14, 18, 17, 21,
       22, 28, 27, 20, 16, 13, 19, 25, 15, 23, 26, 24]), 35435.162286217244)
(array([ 0,  1,  5,  4,  3,  7,  6,  2,  8, 12, 11,  9, 10, 14, 18, 20, 27,
       28, 22, 21, 16, 17, 13, 19, 25, 24, 26, 23, 15]), 35335.803942168292)
(array([ 0,  1,  5,  4,  3,  7,  6,  2,  8, 12,  9, 10, 11, 14, 18, 17, 22,
       21, 28, 27, 20, 16, 13, 19, 25, 24, 26, 23, 15]), 35224.351820726755)
(array([ 1,  0,  5,  4,  3,  7,  2,  6,  8, 10,  9, 11, 12, 13, 16, 17, 14,
       18, 21, 22, 28, 27, 20, 19, 25, 24, 26, 23, 15]), 34564.394451207634)
(array([ 1,  0,  5,  4,  3,  7,  2,  6,  8, 12, 11, 10,  9, 14, 18, 17, 22,
       21, 28, 27, 20, 16, 13, 19, 25, 24, 26, 23, 15]), 34368.165440519064)
(array([ 1,  0,  5,  4, 10,  9, 11,  7,  3,  2,  6,  8, 12, 13, 17, 16, 14,
       18, 21, 22, 20, 28, 27, 19, 25, 24, 26, 23, 15]), 33822.885517663948)
(array([ 1,  0,  5,  4, 10,  9, 11,  7,  3,  2,  6,  8, 12, 13, 14, 18, 17,
       16, 21, 20, 22, 28, 27, 19, 25, 24, 26, 23, 15]), 33622.642976303672)
(array([ 0,  1,  5,  4,  3,  7,  9, 10, 11,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 19, 25, 24, 26, 23, 15]), 33587.532948546519)
(array([ 1,  0,  5,  4,  3,  7,  9, 10, 11,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 20, 22, 28, 27, 25, 19, 24, 26, 23, 15]), 33388.538063308915)
(array([ 1,  0,  5,  4, 10,  9, 11,  7,  3,  2,  6,  8, 12, 13, 16, 14, 18,
       17, 21, 22, 20, 28, 27, 19, 25, 24, 26, 23, 15]), 33070.578249782215)
(array([ 1,  0,  5,  4,  9, 10, 11,  7,  3,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 19, 25, 24, 26, 23, 15]), 32672.906253706591)
(array([ 0,  1,  5,  4, 10,  9, 11,  7,  3,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 19, 25, 24, 26, 23, 15]), 32651.195071372633)
(array([ 1,  0,  5,  4, 10,  9, 11,  7,  3,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 20, 22, 28, 27, 25, 19, 24, 26, 23, 15]), 32452.200186135022)
(array([ 1,  0,  5,  4, 10,  9, 11,  7,  3,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 25, 19, 24, 26, 23, 15]), 32368.098873641153)
(array([ 1,  0,  5,  4,  9, 10, 11,  7,  3,  2,  6,  8, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 25, 19, 24, 26, 23, 15]), 32316.888332004622)
(array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14,
       18, 21, 20, 22, 28, 27, 25, 19, 24, 26, 23, 15]), 31822.056301401353)
(array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 25, 19, 24, 26, 23, 15]), 31737.954988907484)
(array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 25, 19, 15, 23, 26, 24]), 31681.769910060932)
(array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14,
       18, 21, 20, 22, 28, 27, 25, 19, 15, 24, 26, 23]), 31609.936193800866)
(array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 18,
       14, 21, 22, 20, 28, 27, 25, 19, 15, 24, 26, 23]), 31602.760445425949)
(array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 25, 19, 15, 24, 26, 23]), 31525.83488130699)
(883, 51214, (array([ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14,
       18, 21, 22, 20, 28, 27, 25, 19, 15, 24, 26, 23]), 31525.83488130699))

Final solution

wi29

t = 883, n = 51214

[ 0,  1,  5,  4,  3,  2,  6,  8,  7,  9, 10, 11, 12, 13, 16, 17, 14, 18, 21, 22, 20, 28, 27, 25, 19, 15, 24, 26, 23]
31525.83488130699

dj38

t = 1552, n = 117952

[28, 29, 31, 34, 36, 37, 32, 33, 35, 30, 26, 27, 23, 21, 24, 25, 22, 19, 14, 12, 15, 16, 17, 18, 10, 11,  8,  7,  6,  5,  4,  2,  3,  1, 0,  9, 13, 20]
8021.0298369392722)

In [ ]: