[研究ノート] TSPのGAソリューション

TSPのGAソリューション

遺伝的アルゴリズム

ブログを最大化するための遺伝的アルゴリズムの前に書かれた、TSPのためのコードを解くことについての記録に入ることはありません。
アルゴリズムは非常に単純で、唯一の注意点は、問題を定義する方法である、交叉オペレータ、突然変異オペレータやフィットネス機能が言いました。
水、あまりにも眠い学校の先生、聞いて、書き込み-

問題の表現

アクセスシーケンスは、3つのサンプルノードは、[2,1,0] IIは、ノード0が最後にアクセスされた、第1のアクセス・ノードとアクセスノード1を表すように、配列のセットによって表すことができる、配列のセットによって表されます。
したがって直接np.random.shuffle(np.arange(n))をサンプルのサンプルを生成する生成することができます。

クロスオーバー

この問題は、このような配列[2,1,3,4,0]と配列[1,2,3,4,0] 0〜3の間の位置で交差するような2つの配列間の交差点に関するしかし、直接交換は、重複する番号の交換をサンプルにつながるので、私が設計したときに、直接これらの場所をシャッフルすることができます。
本質的に交差実装していないが、クロスの重要性は、実際には、両方の良い遺伝子の存在が保持され、ランダムに選択された場所が良い遺伝子であってもよいし、なくてもよく、良好な遺伝子の相互交換により、私は実際には、この操作は、ローカルと同等です変異が良くない場合には変動が、親を維持しながら、それは、親の局所的な変化のために良いですが、外に排除されます。が、デザインは非常に良いではありませんが、結果は仕事でした。

突然変異オペレータ

突然変異オペレータがより良い実装され、ランダムに選択された間隔は、ランダム配列間隔で破壊することができます。

コーディング

import numpy as np

class GA(object):
    def __init__(self,cities,num_iters = 250):
        self.cities = cities
        self.num_iters = num_iters
        init_number = 500
        n = self.cities.shape[0]
        self.weight = np.tile(np.arange(n)[np.newaxis,:],[init_number,1]) # 种群初始化数量为100个个体
        for i in range(n):
            np.random.shuffle(self.weight[i])
        self.distance = np.zeros((n,n))
        for i in range(n):
            for j in range(n):
                self.distance[i,j] = np.linalg.norm(self.cities[i] - self.cities[j])
    def solve(self):
        for iter in range(self.num_iters):
            
            n = self.weight.shape[0]
            w = [self.fitness(self.weight[i]) for i in range(n)]
            print(sum(w) / len(w))
            w/= sum(w)
            probablity = [sum(w[:i+1]) for i in range(len(w))]
            new_x = []
            for _ in range(n):
                p = np.random.random()
                for j in range(n):
                    if j ==0:
                        if p >=0 and p <= probablity[j]:
                            temp = self.weight[j].copy()
                            q = np.random.random()
                            if q > 0.4:
                                self.variation(temp)
                            new_x.append(temp)
                            break
                    else:
                        if p >= probablity[j-1] and p <= probablity[j]:
                            temp = self.weight[j].copy()
                            q = np.random.random()
                            if q > 0.4:
                                self.variation(temp)
                            new_x.append(temp)
                            break
            fm = sorted(new_x,key = lambda x:self.fitness(x))[0:2]
            new_x.extend(self.cross(fm[0],fm[1]))
            
            self.weight = np.array(new_x)
        result = sorted(self.weight.tolist(),key = lambda x:self.fitness(x))[-1]
        print(result,1./self.fitness(result))
    @staticmethod
    def variation(x):
        n = x.shape[0]
        a = np.random.randint(0,n-1)
        b = np.random.randint(0,n-1)
        a,b = (b,a) if b<a else (a,b)
        np.random.shuffle(x[a:b])
    @staticmethod
    def cross(x,y):
        n = x.shape[0]
        a = np.random.randint(0,n-1)
        b = np.random.randint(0,n-1)
        a,b = (b,a) if b<a else (a,b)
        xx = x.copy()
        yy = y.copy()
        np.random.shuffle(xx[a:b])
        np.random.shuffle(yy[a:b])
        #xx[a:b],yy[a:b] = yy[a:b],xx[a:b]
        return [xx,yy]


    def fitness(self,x):
        n = self.cities.shape[0]
        fit = 0.
        for i in range(n):
            j = i+1 if i+1 <n else 0
            fit += self.distance[x[i],x[j]]
        return 1./fit

if __name__ == "__main__":
    #cities = np.array([[0,0],[0,1],[1,0],[1,1]])
    cities = np.array([[2,6],[2,4],[1,3],[4,6],[5,5],[4,4],[6,4],[3,2]])
    # [2, 1, 0, 3, 5, 4, 6, 7] 16.084259940083065

    solver = GA(cities)
    #print(1./solver.fitness(np.array([1,2,0,3,5,4,6,7]))) # 17.246537600251443
    #solver.solve()

結果

[2、1、0、3、5、4、6、7] 16.084259940083065

ホップフィールド感とネットワークが、実際には、各実行の結果は、私は、総距離は少し良く、これよりも、より良い14.714776642118863あり、また違いの場合よりもそこで実行されている走ったホップフィールド、同じではありません。4つのノードのような少ないランノードが、結果は絶対的に正しい、ノードは、もう少し不安定であってもよいです。(私は、はるかがあるのか​​分からないので、最小距離/)

おすすめ

転載: www.cnblogs.com/aoru45/p/12553188.html