0

ユーザー入力を整数の形式で受け取るプログラムがあります。それをkと呼びましょう。他に a、b、c の 3 つの数が知られています。私の仕事は、ax + by + cz = k となるすべての正の整数解 {x,y,z} を見つけることです。a、b、および c が組み込まれているオブジェクトに対して呼び出すメソッドを作成しました。x + y + z が既知の整数 p を超えることはできないという追加の制約があります。

    def find_all_solutions(self, k):
        for x in range(0, k/c +1):
            for y in range(0, k/c +1):
                for z in range(0,k/c +1):
                    if x+y+z <= self.p and self.a*x+self.b*y+self.c*z == k:
                        one_solution = [x,y,z]
                        list_of_combinations.insert(END,"x: {0}, y: {1}, z: {2} ".format(one_solution[0], one_solution[1], one_solution[2]))
    K = IntVar()
    KassaBox= Entry(TeaterGUI, relief=GROOVE,textvariable=Kassa,width="15")
    KassaBox.place(x="400",y="240")


    KombinationsKnapp = Button(TeaterGUI, text="Tryck har for att visa alla mojliga kombinationer", command= lambda: TeaterLista[Teater_Index.get()].find_all_solutions(K.get()))
    KombinationsKnapp.place(x="400",y="260")

これは、k がやや小さい (<100000) 場合に機能しますが、3 桁を超えると、インタープリターは計算を行うときに数秒間フリーズしますが、最終的には想定どおりに動作します。

私の問題は、k が大きい場合、チェックする必要がある組み合わせの量が多すぎて、Python インタープリターで処理できないことです。

したがって、これらのクラッシュを回避する方法は、プログラムがすべてのソリューションを見つけて一度に追加するのではなく、プログラムに各ソリューションを見つけてリストボックスに1つずつ追加することだと考えていました。コンピュータが使用前に RAM に多くの情報を保存するのを避けるため。ただし、 tkinters .insert メソッドがリストボックスに情報を追加する唯一の方法のように見えるため、これを行う方法がわかりません。

どんな助けでも大歓迎です!

4

1 に答える 1

-1

この行の代わりに:

list_of_combinations.insert(END,"x: {0}, y: {1}, z: {2} ".format(one_solution[0], one_solution[1], one_solution[2]))

あなたができる:

yield "x: {0}, y: {1}, z: {2} ".format(one_solution[0], one_solution[1], one_solution[2])

次に、リストボックスに追加するには、単純な反復ループを実行できます。

for solution in find_all_solutions(k):
    listbox.insert("end", solution)

これにより、ジェネレーター関数が一度に 1 つの回答を生成し、リストボックスに次々と追加できるようになります。

ただし、これが行われている間はプログラムが に到達しないmainloopため、ウィンドウが更新されることはありません。すべての挿入の間に手動で呼び出すことができますがwindow.update()、これにより計算が遅くなります。

いくつかのより良いオプションは次のとおりです
。1) この計算ループに入る前に、次のような関数を追加します。

def myupdate():
    window.update()
    window.after(100, myupdate)

ループを開始する直前に、次のような行を追加します。

window.after(100, myupdate)

ウィンドウが約100ミリ秒ごとに更新されるスレッド更新ループを効果的に開始します

2)非常に多くの挿入ごとにウィンドウを更新する別のサブループを追加します

例えば:

a = 0
for solution in find_all_solutions(k):
    listbox.insert("end", solution)
    a += 1
    if a == 10: #would update every 10 inserts
        window.update()
        a = 0
于 2014-09-09T14:17:07.147 に答える