0

他のことを言う前に、問題は長く見えるかもしれませんが、実際にはコアの 1 つの問題にすぎず、そのようなことが繰り返されます。確率に関係する「パズル ソルバー」を作成しようとしています。これは、問題を解決する人がコンピューターの助けを借りずに解決しなければならないモデルですが、さまざまな条件の変数を変更するだけのスクリプトを作成できるようにしたいと考えています。私たちはこのテストを潜在的な従業員に使用し、答えを考え出さなければなりません. それはかなり退屈なので、誰かがPythonでそれをやろうとして手を貸してくれることを望んでいましたか? 私はまだPythonを学んでいますが、誰もがPythonを「操作」して必要なものを提供できることがわかっているので、その方法を学びたいと思っていたので、これを何度も手作業で行う必要はありません.

これがテストの例です -

与えられた事実:

  1. 5 家が並んでいて、左から 1、2、3、4、5 と番号が付けられています。
  2. 各家は、赤、オレンジ、黄、緑、または青の異なる色で塗装されています。
  3. 各家の所有者は、アン、ボブ、カール、ドロシー、エドの 3 人です。
  4. 家ごとに窓の数が異なります: 1、2、3、4、5
  5. 各家は、1970 年、1980 年、1990 年、2000 年、または 2010 年という異なる年に建てられました。
  6. スペイン語、フランス語、ラテン語、ドイツ語、イタリア語など、それぞれの人が異なる言語を知っています。

次に、制約を与えます。

  1. ボブは黄色い家に住んでいます。
  2. アンはラテン語を知っています。
  3. オレンジ色の家には 5 つの窓があります。
  4. ドロシーは窓が2つある家に住んでいます。
  5. オレンジハウスはグリーンハウスのすぐ右側にあります。
  6. ドイツ語話者は 2000 年に建てられた家に住んでいます。
  7. 赤い家は 1970 年に建てられました。
  8. 真ん中の家には3つの窓があります。
  9. カールは最初の家に住んでいます。
  10. 1980年に建てられた家は、イタリア語話者の家の隣にあります。
  11. 1970年に建てられた家は、フランス語話者が住んでいる家の隣にあります。
  12. 1990年に建てられた家には窓が1つあります。
  13. Ed は 2010 年に建てられた家に住んでいます。
  14. カールは青い家の隣に住んでいます。

潜在的な従業員は、次のことを把握する必要があります。

1 から 5 までの番号が付けられた各家屋について、そこに住んでいる人、家の色、窓の数、建てられた時期、住人が話す言語。そして、それこそまさに私が Python に入れたいものです!

私はそれを試してみましたが、その背後にある私の理由は次のとおりです。

def permutations(x):
    outlist = []
    for a in x:
        for b in x:
            if b == a:
                continue
            for c in x:
                if c == b or c == a:
                    continue
                for d in x:
                    if d == a or d == b or d == c:
                        continue
                    for e in x:
                        if e == a or e==b or e==c or e==d:
                            continue
                        outlist.append([a,b,c,d,e])
    return outlist

ループ内の「チェック」は、エントリが繰り返される場合にループが続行されるようにするためのものであり、初期のループが有効でない限り内側のループを実行する必要はありません - 時間を節約できます!

5 つの要素のリスト x を指定すると、この関数はリストのリストを返します。各リストは、元の 5 つの要素の順列であり、どの要素も他の要素と等しくありません。したがって、リスト入力が x = [1,2,3,4,5] の場合、返される出力は、これの可能な順列のリストです。

Outlist = [[1,2,3,4,5],[1,2,3,5,4],[1,2,4,3,5],[1,2,4,5,3], ...]

5になります!= 120 要素。

したがって、理論的にはどのように機能するかはわかっていますが、Python で書き留めると、「翻訳」するのに多くのことがわかりました。

名前変数 (Ann、Bob、Carl、Dorothy、Ed) にこれらの順列 ([1,2,5,4,3] など) の 1 つを割り当てました。これは、Ann が家 1 に住んでいて、Bob が家 2 に住んでいることを意味します。キャロルは5号館、ドロシーは4号館、エドは3号館に住んでいます。

同様に、色変数 (赤、オレンジ、黄、緑、青) に別の順列 ([5,4,3,1,2] など) を割り当てることができることを知っています。つまり、家 5 は赤、家 4 です。はオレンジ色、家 3 は黄色、家 1 は緑、家 2 は青です。

窓の数 (1、2、3、4、5)、家が建てられた年 (7、8、9、0、10)、話されている言語に、同じまたは別の順列を割り当てることができます。

同じ数字を再利用する方法を理解するのに苦労しているので、これは私が本当に迷子になるところです - そのような場合、それらは上書きされませんか?

ただし、まず最初に、手がかりがこの割り当てに当てはまるかどうかを最初に確認する方が良いです (時間効率が良くなります)。そうでない場合、テストを受ける人は別の課題に行くことができます!

コーディングに関しては、これが私が想像した方法ですが、Python に関する私の限られた知識は、「適切なコード」を書くのに実際には役立ちませんでした。

a) check if Bob lives in the yellow house, by Bob == Yellow 

(つまり、Bob に割り当てられた家番号は、Yellow に割り当てられた家番号と同じです。b) 1970 年に建てられた家がフランス語話者が住んでいる家の隣にあるかどうかを確認し、絶対値計算を行います ->

abs(Seven – French) == 1

つまり、Seven と French に割り当てられた番地の違いは 1 だけです。

さらに、追加のチェックがあり、5 つの順列割り当てがパズルの解決策になるには、それらすべてが True として渡される必要があることを知っています。

次に、ループを使用して変数への順列の割り当てを行いました。

for a in outlist:
    (Ann,Bob,Carl,Dorothy,Ed) = a

Ann に値 a[0]、Bob に値 a[1]、Carol に値 a[2]、Dorothy に値 a[3]、Ed に値 a[4] を割り当てます。すべての順列をループするためです。ここで、outlist は関数の出力、順列リストのリストです。

もう 1 つの問題 - リストのリストを作成する... 少し苦労していることを示しています。

関心のある変数への代入の 5 つのネストされたループを作成する必要があることはわかっています。代入が手がかりを満たしているかどうかを検証するために、部分的な代入を取得したら、各ループで手がかりのサブセットを段階的にチェックすることを考えました。そのため、手がかりのサブセットが満たされない限り、内側のループを列挙しません。繰り返しになりますが、プログラムの実行速度が向上し、より効果的になります。

これは、(たとえば) 名前に関する最初のループの試みです。Carl は家 1 に住んでいなければならないことはわかっています。そうでない場合、他のループは実行されません。紙の上では、カール == 1 になるまでこのプロセスを繰り返さなければなりません!

コードを書く試み:

for a in outlist:
(Ann,Bob,Carl,Dorothy,Ed) = a
if Carl != 1:
    continue
for b in outlist:
    (Red,Orange,Yellow,Green,Blue) = b
    if ...  

このコードでは、内側の 4 つのループは Carl == 1 の場合にのみ実行されます。続行する必要があることはわかっていますが、ここでも変数のオーバーラップが問題になります。

そして最後に-timeモジュールを使用して「関数の時間を計る」ようにアドバイスされました

time.time().  

Mac(私のもの)で報告される現在の時刻はマイクロ秒単位であることを知っており、これはそれに基づいて書かれています。正しいコードを取得する方法がわかりません。

import time
start = time.time()
#CODE
end = time.time()
print('Running Time: {} msecs'.format((end - start)*0.001))

最後までお付き合いいただきありがとうございました!私はそれが非常に圧倒され、どこから始めればよいかわかりませんが、私のためにすべての順列を行うこのようなものを持っていたいと思っています!

4

1 に答える 1

1

itertools.permutations()順列を生成するために使用します。

from itertools import permutations

for colors in permutations(range(5)):
    # colors is permuted combination of 5 integers between 0 and 4, inclusive.

これは Python にとってより自然な 0 から 4 までの数字を使用しますが、原理は同じです。range(1, 6)必要に応じて、代わりに 1 から 5 までの整数の順列を生成するために使用できます。

次に、順列ループをネストします。外側のループは色の選択用です。その家の色を表す各数字。制約をテストし、適合しないものをすべて排除します (緑の隣にオレンジがない組み合わせは適合しません)。制約が適合する場合は、所有者の順列をループし、適合しないものを削除し、適合するウィンドウ カウントをループします。

1 つの関数を使用して制約をテストし、欠落している側面を考慮して、テストをシンプルに保ちます。

ほとんどのコンボを非常に早い段階で非常に迅速に排除できることがわかります。

于 2013-04-27T08:17:12.447 に答える