61336


Pythonを勉強して間もない者です。参考書やネット等で調べたのですが、理解が及ばなかった為、こちらで質問させていただきます。

このプログラムは初期値（V,E）を元に関数IDISTで計算した値を、default_valueとしています。またV＝（０，１，２，３，４）を置換したものをpi[]とし１２０通りの置換したpi[]を元に、新たにnew_Eというエッジを作成し、置換した一つ一つのVを元に、関数IDISTでnew_Eを計算しています。計算したnew_EのIDISTとdefault_valueの値を比較し、小さい方を出力するというのがこのプログラムです。

このプログラムの出力結果として

[code]

    （０，１，２，３，４）
    　１２
    （０，１，２，４，３）
    　１０
    （０，１，３，４，２）
    　１１
    
[/code]

と全通り出力されていくのですが、私はこのプログラムを１２０通りの中でIDISTが最も最小なものと、その時の置換pi[]のみを出力したいのです。ですがそのようにする上手い方法が思いつきません。拙い文章ではありますが、どなたかアドバイスを頂けたら幸いです。

**目標となる出力**

[code]

    最小コスト　２
    その時の置換　（１，４，０，３，２）
    　　　　　　　（１，４，２，０，３）
    　　　　　　　（１，４，２，３，０）
    　　　　　　　（２，０，１，４，３）
    　　　　　　　（２，０，３，１，４）
    　　　　　　　（２，０，３，４，１）
    
[/code]

**ソースコード**

[code]

    class Edge():
        def __init__(self,a,b,c):
            self.u = a
            self.v = b
            self.weight = c
        def __str__(self):
            return '(' + str(self.u) + ',' + str(self.v) + ',' + str(self.weight) + ')'
    
    class Graph():
        def __init__(self,d,e):
            self.V = d
            self.E = e
    
    import itertools
    
    V = tuple(range(0, 5)) # tuple of integers
    E = (Edge(0,3,1), Edge(0,2,3), Edge(0,4,2), Edge(2,4,1))
    G = Graph(V, E)
    
    def iDist(V,E):
        value = 0
        for e in E:
            value += e.weight * abs(abs(e.u - e.v)-1)
        return value
    
    default_value = iDist(V,E)
    min_sum = []
    
    for pi in itertools.permutations(V):
        new_E =  (Edge(pi[0],pi[3],1), Edge(pi[0],pi[2],3), Edge(pi[0],pi[4],2), Edge(pi[2],pi[4],1))
        min_sum = min(default_value, iDist(pi,new_E))
        print(pi)
        print(min_sum)
    
[/code]


CC BY-SA 4.0
2019-12-11T05:10:51.037
61335
2019-12-11T09:55:42.590
2019-12-11T09:55:42.590
19110
34359
question
python python3
最小値とその時の状態を出力したいが、どのようにプログラミングすればよいかわからない。


現状は for 文の中に `print(min_sum)`
が入っているため、すべての繰り返しで出力されてしまっています。最小値は繰り返しきった後に確定するため、for の外側に出す必要があります。

[code]

    for pi in itertools.permutations(V):
        (... コード ...)
    print(min_sum)  # インデントを下げて for の外に出す。
    
[/code]

また、出力したいのは「最小値とそのときの `pi`」なので、`min_sum` の他に `min_pi`
も覚えておく必要があります。そうするためには最小値を `min` 関数で求めるのではなく if 文で分岐させる形にすると良いです。

[code]

    for pi in itertools.permutations(V):
        new_E =  (Edge(pi[0],pi[3],1), Edge(pi[0],pi[2],3), Edge(pi[0],pi[4],2), Edge(pi[2],pi[4],1))
        current_sum = iDist(pi, new_E)
        if current_sum < min_sum:
            min_sum = current_sum
            min_pi = pi
    print(min_pi)
    print(min_sum)
    
[/code]

※毎回 `default_value` と比較してしまっていたバグもこっそり直しています。

なお、これだと最小値をとる `pi` がひとつしか分かりません。もし最小値をとる `pi`
をすべて求めたいのであればもう少し工夫する必要があります。たとえば：

[code]

    for pi in itertools.permutations(V):
        new_E =  (Edge(pi[0],pi[3],1), Edge(pi[0],pi[2],3), Edge(pi[0],pi[4],2), Edge(pi[2],pi[4],1))
        current_sum = iDist(pi, new_E)
        if current_sum < min_sum:
            min_sum = current_sum
            min_pis = [pi]
        elif current_sum == min_sum:
            min_pis.append(pi)
    print(min_pis)
    print(min_sum)
    
[/code]


CC BY-SA 4.0
2019-12-11T05:42:23.950
61336
2019-12-11T05:42:23.950
19110
61335
answer