0

私の目標は、ツアーのリストを作成することです。各ツアーもリストです。

このコードの問題は、ループの最後で、toursリストが別のシャッフルされたツアーのリストではなく、リストに追加された最後のツアーのリストになることです。これはPythonオブジェクト参照に関係していると思いますが、これを変更する方法がわかりません。私は試してみdel tourましたが、役に立ちませんでした。

def initialisePopulation(self, cities):
    tours = []

    for i in xrange(0, PopulationSize):
        tour = Tour(cities)
        shuffle(tour.tour)
        tours.append(tour)
        print str(tour.tour[0].id) + "," + str(tour.tour[1].id) + "," + str(tour.tour[2].id) + "," + str(tour.tour[3].id) + "," + str(tour.tour[4].id)
        del(tour)
    print "-"
    for j in xrange(0, PopulationSize):
        print str(tours[j].tour[0].id) + "," + str(tours[j].tour[1].id) + "," + str(tours[j].tour[2].id) + "," + str(tours[j].tour[3].id) + "," + str(tours[j].tour[4].id)

各ツアーを印刷すると、すべて問題ありません。の内容を印刷するとtours、各項目は同じです。出力は次のとおりです。

2,3,1,5,4
2,4,3,1,5
2,3,4,1,5
4,3,1,5,2
3,4,1,5,2
-
3,4,1,5,2
3,4,1,5,2
3,4,1,5,2
3,4,1,5,2
3,4,1,5,2

ツアークラス:

class Tour(object):
    '''
    classdocs
    '''

    def __init__(self, cityList):
        self.tour = cityList
        self.size = len(cityList)
        self.fitness = self.getFitness(self.tour)

    def getFitness(self, tour):
        fitness = sum([self.euclideanDistance(tour[i], tour[i+1]) for i in xrange(0, self.size-1)])
        return fitness

    def euclideanDistance(self, p, q):
        distance = sqrt((p.x - q.x)**2 + (p.y - q.y)**2)
        return  distance
4

1 に答える 1

3

ここで 2 つの間違いのうちの 1 つを犯していることはほぼ確実ですが、それはあなたが示していないコードにあるため、どちらが間違っているのかわかりません。

tour最初の可能性は、Tours のインスタンス属性ではなくクラス属性として保存しているため、すべて同じ属性を共有していることです。

class Tour(object):
    tour = something

2 番目の可能性は、都市のリストをtourインスタンス属性にコピーしているため、すべて異なる属性を持っていますが、それらはすべて同じリスト値への参照です。

class Tour(object):
    def __init__(self, cities):
        self.tour = cities

あなたの更新された質問から、それは2番目のものです。

これは最終的に多次元リストに関する FAQと同じですが、リストのリストを直接持つ代わりに、それぞれがリストをラップするオブジェクトのリストを持っている点が異なります。

とにかく、それぞれTourに個別のリストが必要なので、 のような関数で個別に変更できますよshuffleね? 次に、リストをどこかに明示的にコピーする必要があります。例えば:

class Tour(object):
    def __init__(self, cities):
        self.tour = cities[:]

しかし、私はおそらくこれを別の方法で書くでしょう。最初に、その場で変更せず、代わりに新しいリストを返すshuffledメソッドを作成しました。

def shuffled(iterable):
    result = list(iterable)
    shuffle(result)
    return result

次に、最初のループ全体を次のように置き換えることができます。

tours = [Tour(shuffled(cities)) for _ in xrange(PopulationSize)]

途中で、2 番目のループを次のように置き換えることができます。

for tour in tours:
    print ','.join(city.id for city in tour)

ループに関するチュートリアルでforは、その部分について説明していますfor tour in tours。2 行目では、5 回の繰り返しを避けるための理解と方法を使用しています。join

于 2013-11-06T00:00:09.880 に答える