Exemplo n.º 1
0
    def run(self, *args):
        if self.mode == 'add' or self.mode == 'edit':
            self.beforeRunMode = self.mode
            self.mode = 'run'
            self.idx = 0
            self.lines = []
            self.vertice = []
            self.linesaver = []
            self.btnRun.configure(state='disabled')
            self.btnAdd.configure(state='disabled')
            self.btnEdit.configure(state='disabled')
            self.btnClear.configure(state='disabled')
            self.btnRandom.configure(state='disabled')
            self.btnStop.configure(state='normal')
            self.btnAbout.configure(state='disabled')
            comboval = self.getComboVal()
            self.myobject.DelMyVertexAll()
            self.myobject.DelMyLineAll()
            self.myobject.DelMyMstAll()
            allvertex = self.secondcanvas.find_withtag('circle')
            alllines = self.secondcanvas.find_withtag('line')
            vertexnya = []
            ### 2 for dibawah gae opo ? ###
            # Buat komputasi, kan butuh data line nya terhubung vertex apa aja
            # beratnya berapa
            # object vertex ga terlalu berguna kalau ndak ada fitur random jumlah vertex & line
            for i in allvertex:
                currentvertextag = self.secondcanvas.gettags(i)
                vertexholder = Vertex()
                # print(currentvertextag)
                vertexholder.SetTag(currentvertextag)
                vertexholder.SetIdx(int(currentvertextag[0][1:]))
                vertexnya.append(vertexholder.GetIdx())
                self.myobject.PushMyVertex(vertexholder)

            if (self.myobject.GetMyVertexSize() == 0):
                messagebox.showwarning("Error occured!", "Tidak ada vertex!")
                return

            for i in alllines:
                currentlinetag = self.secondcanvas.gettags(i)
                # print(currentlinetag)
                lineholder = Line()
                lineholder.SetWeight(int(currentlinetag[4]))
                lineholder.SetTag(currentlinetag)
                lineholder.SetVAll(
                    (int(currentlinetag[1][3:]), int(currentlinetag[3][3:])))
                self.myobject.PushMyLine(lineholder)

            note = 1
            if comboval == 'Djikstra':
                self.log('Running Djikstra !')
                self.popWindow(
                    labeltext="Masukkan titik keberangkatan vertex :")
                self.wait_window(
                    self.top
                )  #self.top -> variable yg menyimpan object popwindow / dialog
                start = self.popvalue  #popvalue itu yang nyimpan valuenya
                self.popWindow(labeltext="Masukkan titik tujuan vertex :",
                               popvalue=2)
                self.wait_window(self.top)
                end = self.popvalue
                # self.vertice.append((0,start))
                if (self.myobject.GetMyLineSize() == 0):
                    return  #kalau gak ada line nya ndak ada yg harus di-compute
                # self.secondcanvas.itemconfigure('line',state='hidden')
                process = self.myobject.Compute('Djikstra',
                                                val1=start,
                                                val2=end)
                for i in allvertex:
                    x, y, x1, y1 = self.secondcanvas.coords(i)
                    tag = self.secondcanvas.gettags(i)
                    self.secondcanvas.create_text(x + 20,
                                                  y - 15,
                                                  text="-",
                                                  font=(200),
                                                  tags=('w' + str(tag[0][1:]),
                                                        'weight'),
                                                  fill='blue')
                self.secondcanvas.itemconfigure('w' + str(start), text=str(0))
                for i in range(0, len(process)):
                    routehold = process[i][1]
                    routeme = []
                    for j in range(0, self.myobject.GetMyLineSize()):
                        lholder = self.myobject.GetMyLineAt(j)
                        v = lholder.GetVend()
                        w = lholder.GetVstart()
                        ltag = lholder.GetTag()
                        lobj = self.secondcanvas.find_withtag(ltag[0])
                        # print(process[i])
                        # print(str(v)+" "+str(w))
                        if (len(routehold) - 1 != 0):
                            for k in range(0, len(routehold) - 1):
                                if (v == routehold[k]
                                        and w == routehold[k + 1]):
                                    routeme.append(lobj)
                                    # print("-"+ str(ltag))
                                elif (v == routehold[k + 1]
                                      and w == routehold[k]):
                                    routeme.append(lobj)
                                    # print("-"+str(ltag))
                        if (process[i][0] == v and process[i][2] == w):
                            routeme.append(lobj)
                            # print(ltag)
                        elif (process[i][0] == w and process[i][2] == v):
                            routeme.append(lobj)
                            # print(ltag)
                    # print(routehold)
                    # print("----")
                    # print(process[i])
                    #kari update bobote
                    self.vertice.append((process[i][3], process[i][2]))
                    self.linesaver.append(routeme)

                self.animatedjikstra()
                # self.secondcanvas.itemconfigure('line',fill='blue')

            elif comboval == 'Prims':
                self.log('Running Prims !')
                if (self.myobject.GetMyLineSize() == 0):
                    return  #kalau gak ada line nya ndak ada yg harus di-compute
                self.popWindow(labeltext='Masukkan sembarang Vertex')
                self.wait_window(self.top)

                completed = False
                while (not completed):
                    for i in range(0, len(vertexnya)):
                        if (self.popvalue == vertexnya[i]):
                            completed = True
                            break
                    if (not completed):
                        messagebox.showwarning("Error Occured",
                                               "Vertex tidak ada!")
                        self.popWindow(labeltext='Masukkan sembarang Vertex')
                        self.wait_window(self.top)

                pholder = self.myobject.Compute('Prims',
                                                val1=self.popvalue,
                                                val2=self.vertexNum + 1)
                animatedprims = pholder[0]
                self.vertice = pholder[1]
                for i in range(0, len(animatedprims)):
                    self.animatedprim.append([])
                    for j in range(0, len(animatedprims[i])):
                        vholder = animatedprims[i][j]
                        for k in range(0, self.myobject.GetMyLineSize()):
                            curobj = self.myobject.GetMyLineAt(k)
                            realobj = self.secondcanvas.find_withtag(
                                curobj.GetTag()[0])
                            if (vholder[0] == curobj.GetVend()
                                    and vholder[1] == curobj.GetVstart()):
                                # realobj=self.secondcanvas.find_withtag(curobj.GetTag()[0])
                                self.animatedprim[i].append(realobj)
                                break
                            elif (vholder[1] == curobj.GetVend()
                                  and vholder[0] == curobj.GetVstart()):
                                self.animatedprim[i].append(realobj)
                                break
                    #     print(vholder)
                    # print(self.animatedprim[i])
                    # print("----")

            elif comboval == 'Kruskal':
                self.log('Running Kruskal !')
                self.log("1. Sorting Edge berdasarkan beratnya!")
                self.log(
                    "2. Pilih Edge satu-persatu dari yang paling kecil tanpa Loop"
                )
                if (self.myobject.GetMyLineSize() == 0):
                    return  #kalau gak ada line nya ndak ada yg harus di-compute
                cycliclist = self.myobject.Compute('Kruskal',
                                                   val1=self.vertexNum)
                for i in range(0, self.myobject.GetMyLineSize()):
                    lholder = self.myobject.GetMyLineAt(i)
                    if (len(cycliclist) != 0 and i == cycliclist[0]):
                        cycliclist.pop()
                        self.log(
                            str(lholder.GetVstart()) + " - " +
                            str(lholder.GetVend()) + " : " +
                            str(lholder.GetTag()[4]) + " Rejected - Loop!")
                    else:
                        self.log(
                            str(lholder.GetVstart()) + " - " +
                            str(lholder.GetVend()) + " : " +
                            str(lholder.GetTag()[4]) + " Accepted!")
            elif comboval == 'Naive Coloring':
                self.log('Running Naive Coloring !')
                # self.log("")
                colored = self.myobject.Compute('GColor', val1=self.vertexNum)
                note = 2
            elif comboval == 'Fuery':
                self.log("Running Feury")
                self.log(
                    "Eulerian Path is a path in graph that visits every edge exactly once. Eulerian Circuit is an Eulerian Path which starts and ends on the same vertex."
                )
                self.log("===================")
                self.log(
                    "Feury Algorithm is to find the track of that path or circuit"
                )
                self.log(
                    "More about the algorithm on https://www.geeksforgeeks.org/fleurys-algorithm-for-printing-eulerian-path/\n"
                )

                if (self.myobject.Compute('Feury',
                                          val1=self.vertexNum) == False):
                    self.log(
                        "Perhatikan bahwa didalam algoritma ini mempunyai 'arah'"
                    )
                    note = 0
                # self.log('Fuery Run !')
            elif comboval == 'N Max Coloring':
                self.log("Running N Max Coloring")
                self.popWindow(labeltext='Masukkan jumlah maksimal warna!',
                               popvalue=3)
                self.wait_window(self.top)
                nColour = self.popvalue
                colored = self.myobject.Compute('BColor',
                                                val1=self.vertexNum,
                                                val2=nColour)
                for i in range(1, len(colored)):
                    if (colored[i][1] != colored[i - 1][1]):
                        break
                    elif (i + 1 >= len(colored)):
                        if (self.myobject.GetMyLineSize() != 0):
                            note = 99
                            self.log(
                                "Tidak bisa menemukan kombinasi warna-nya!")
                            self.stop()
                if (not colored):
                    note = 99
                    #kasih warning
                    self.log("Tidak bisa menemukan kombinasi warna-nya!")
                    self.stop()
                else:
                    note = 2
            #masukin hasil komputasi ke queue line yg akan ditampilkan
            if (note == 1):
                for i in range(0, self.myobject.GetMyMstSize()):
                    holder = self.myobject.GetMyMstAt(i)
                    if (holder != 'salah'):
                        linetag = holder.GetTag()
                        obj = self.secondcanvas.find_withtag(linetag[0])
                    self.lines.append(obj)
                if (comboval != 'Prims'):
                    if (comboval != 'Djikstra'):
                        self.showline()
                else:
                    self.linesaver = self.lines
                    self.animateprim()
            elif (note == 2):
                # morecolor=[[]]*self.vertexNum
                if (self.myobject.GetMyVertexSize() <= 8):
                    for i in range(0, self.myobject.GetMyVertexSize()):
                        holder = self.myobject.GetMyVertexAt(i)
                        #reuse line untuk menyimpan objek vertex
                        #simpan warnanya di vertice
                        vtag = holder.GetTag()
                        # print(vtag)
                        vholder = self.secondcanvas.find_withtag(vtag[0])
                        self.lines.append(vholder[0])
                        self.vertice.append(colored[holder.GetIdx()])
                    # print(colored)
                else:
                    # print(colored)
                    morecolor = []
                    for i in range(0, self.vertexNum + 1):
                        morecolor.append([])
                    for i in range(0, self.myobject.GetMyVertexSize()):
                        holder = self.myobject.GetMyVertexAt(i)
                        vtag = holder.GetTag()
                        # vholder=self.secondcanvas.find_withtag(vtag[0])
                        # print(holder.GetIdx())
                        # print(colored[holder.GetIdx()])
                        cholder = colored[holder.GetIdx()]
                        morecolor[cholder[1]].append(holder.GetIdx())
                        #warna ke x append indexnya
                        #kayak 'bak' / dikumpulin id vertex sesuai warna
                        # print(morecolor)
                    for i in range(0, self.vertexNum):
                        r = random.randint(0, 255)
                        g = random.randint(0, 255)
                        b = random.randint(0, 255)
                        output = self.rgb2hex(r, g, b)
                        for j in range(0, len(morecolor[i])):
                            colored[morecolor[i][j]] = (True, output)

                    for i in range(0, self.myobject.GetMyVertexSize()):
                        holder = self.myobject.GetMyVertexAt(i)
                        vtag = holder.GetTag()
                        vholder = self.secondcanvas.find_withtag(vtag[0])
                        self.lines.append(vholder[0])
                        self.vertice.append(colored[holder.GetIdx()])
                self.showvertex()
            elif (note == 0):
                self.log(
                    "Graf yang diberikan bukan 'Eulerian Graph' karena memiliki lebih dari 2 vertex yang berderajat ganjil."
                )
                self.stop()