0

I have a program that takes user input in the form of an integer, lets call it k. Three other numbers are known, a,b and c. My task is to find all positive integer solutions {x,y,z} such that ax + by + cz = k. I wrote a method that I call on objects that have a,b and c built in. There is an additional constraint that says that x + y + z cannot be greater than a known integer 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")

This works when k is somewhat small (<100000), although as it exceeds 3 digits the interpreter freezes for a couple of seconds as it does its calculations, but eventually it does what its supposed to.

My problem is that if k is larger, the amount of combinations that have to be checked becomes too many to handle for the python interpreter.

So I was thinking that maybe a way of avoiding these crashes is to, instead of the program finding all solutions and adding them all at once, to make the program find each solution and add it one-by-one to the listbox, so as to avoid the computer storing to much information in its RAM before its used. However, with tkinters .insert method seeming like the only way of appending the listbox with info, I don't know how to do this.

Any help would be greatly appreciated!

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)

这将使您的生成器函数一次产生一个答案,并允许您将它们一个接一个地添加到列表框中。

但是,由于程序永远不会到达发生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 回答