示例#1
0
class TestBinHeap(unittest.TestCase):
    def setUp(self):
        self.theHeap = PriorityQueue()
        self.theHeap.add((2, 'x'))
        self.theHeap.add((3, 'y'))
        self.theHeap.add((5, 'z'))
        self.theHeap.add((6, 'a'))
        self.theHeap.add((4, 'd'))

    def testSize(self):
        assert self.theHeap.currentSize == 5

    def testInsert(self):
        self.theHeap.add((1, 't'))
        assert self.theHeap.heapArray[1] == (1, 't')

    def testContains(self):
        assert 'x' in self.theHeap

    def testDelmin(self):
        assert self.theHeap.delMin() == 'x'
        assert self.theHeap.delMin() == 'y'

    def testDecKey(self):
        self.theHeap.decreaseKey('d', 1)
        assert self.theHeap.delMin() == 'd'
 def shortest_path(self, aGraph, start):
     """
     uses vertex.dist to realize distance between nodes.
     The dist instance variable will contain the current total weight of the smallest
     weight path from the start to the vertex in question.
     Time Complexity: O((V+E)logV)
     :param aGraph: Graph Object
     :param start: vertex Object
     :return:aGraph: Graph Object
     """
     if not isinstance(start, Vertex):
         raise Exception(
             "Value Error: second parameter must be a vertex node")
     pq = PriorityQueue()
     start.setDistance(0)  # we set the distance of source from itself as 0
     pq.buildHeap([(v.getDistance(), v) for v in aGraph])
     # we are building a priority queue of tuple of vertices and their distances from source
     # Initially all distances are set to infinity
     while not pq.isEmpty():
         currentVert = pq.delMin(
         )  # extracts minimum and reconstructs the heap
         for nextVert in currentVert.getConnections():
             newDist = currentVert.getDistance() \
                       + currentVert.getWeight(nextVert)
             if newDist < nextVert.getDistance():
                 # Checking if d[v]<d[u]+w[u,v]
                 nextVert.setDistance(newDist)
                 nextVert.setPred(currentVert)
                 pq.decreaseKey(nextVert, newDist)
                 # decrease key value and reconstructs the heap
     return aGraph
def prims(aGraph, start):

    mse = []
    print "prims from ", start.get_id()
    start.set_distance(0)
    pq = PriorityQueue()
    pq.buildHeap([(v.get_distance(), v) for v in aGraph])

    while not pq.isEmpty():
        currentvertex = pq.delMin()
        #print currentvertex

        mse.append([currentvertex.get_id(), currentvertex.get_distance()])

        currentvertex.set_visited()
        for childvertex in currentvertex.adjacent:
            #print childvertex.get_id()
            newcost = currentvertex.get_weight(childvertex)
            if childvertex in pq and newcost < childvertex.get_distance():
                childvertex.set_distance(newcost)
                childvertex.set_previous(currentvertex)
                pq.decreaseKey(childvertex, newcost)

    for i in mse:
        print i
示例#4
0
def dijkstra(aGraph, start):
    '''Dijkstra’s Algorithm Implementation - Copied from Pythonds Book'''
    '''Edited for Task #1 and Task #2'''
    '''Finding the shortest path from any 'x' vertex to all other vertices in the network.'''
    '''Showing the change after each iteration.'''

    pq = PriorityQueue()
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in aGraph])

    vert_lst = []
    dct = {}
    while not pq.isEmpty():
        lst = []
        currentVert = pq.delMin()
        vert_lst.append(currentVert.getId())
        for nextVert in currentVert.getConnections():
            newDist = currentVert.getDistance() \
                + currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance():
                nextVert.setDistance(newDist)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert, newDist)
                lst.append((nextVert.getId(), newDist))
        dct[currentVert.getId()] = lst

    # The printed changes are in the form of changes occured through a certain
    # vertex that led to a connection with (vertex, cost)
    # Notice that the output may slightly differ in execution(s) due to the
    # implementation of Graph Class using Dictionaries
    iter_count = 1
    for vert in vert_lst:
        print("\tIteration #" + str(iter_count) + "." + " Changes occured through vertex '" + vert +
              "' to find the shortest paths to other vertices for '" + start.getId() + "' are: " + str(dct[vert]))
        iter_count += 1
示例#5
0
    def prims(self, start):
        pq = PriorityQueue()
        entries = dict([(str(v), float('inf')) for v in self.vertices])
        entries[str(start)] = 0
        pq.buildHeap([(float('inf'), v) for v in self.vertices])
        pq.decreaseKey(start, 0)

        new_vertices = []
        new_edges = dict([(x, []) for x in self.vertices])

        last = dict([(str(x), None) for x in self.vertices])

        while not pq.isEmpty():
            current = pq.delMin()
            new_vertices.append(current)

            clast = last[str(current)]

            if clast:
                new_edges[clast].append(current)

            for v in self.adj[current]:
                dist = v[1]
                old = entries[str(v[0])]
                if old > dist:
                    entries[str(v[0])] = dist
                    last[str(v[0])] = current
                    pq.decreaseKey(v[0], dist)

        return Graph(new_vertices, new_edges)
示例#6
0
def dijkstra(aGraph, originPt):

    unvisitedPriorityQ = PriorityQueue()
    originPt.setDistance(0)
    # init with TUPLE of CUMULATIVE distance from Origin TO given unvisited point
    unvisitedPriorityQ.buildHeap([(unvisitedPt.getDistance(), unvisitedPt)
                                  for unvisitedPt in aGraph])

    while not unvisitedPriorityQ.isEmpty():
        # ATTN:  next nearest point can be attached to ANY point in already VisitedShortestPathPoints
        #        where MULTIPLE PARALLEDLSHORTEST PATHs from ORIGIN are supported;
        #        and which has the MIN Cumulative distance calculated from Origin SO FAR!
        # ATTN:  this just CONSUMEs next nearest point; SHRINKING unVisited points set!
        #nextNearestPt = unvisitedPriorityQ[0]
        nextNearestPt = unvisitedPriorityQ.delMin()
        # TODO DEBUG:  need to find out why 0th point of internal heapArray is not removed; and returned as nextNearestPt
        for adjacentPt in nextNearestPt.getConnections():
            # ATTN:  *.getWeight() gets weight on EDGE between points
            #        *.getDistance() gets CUMULATIVE distance from Origin TO point
            nextAdjacentPtUpdatedCumDist =  nextNearestPt.getDistance() \
                                          + nextNearestPt.getWeight(adjacentPt)
            # ATTN:  only update cumulative distance on adjacent Point to priority NEXT NEAREST POINT IFF
            #        cumulative distance from origin to this adjacent Point is LESS than current cum dist on adjacent Point!
            if nextAdjacentPtUpdatedCumDist < adjacentPt.getDistance():
                adjacentPt.setDistance(nextAdjacentPtUpdatedCumDist)
                # ATTN:  - sets predecessor to BUILD one PARALLEL SHORTEST PATH LINKs!
                adjacentPt.setPred(nextNearestPt)
                # ATTN:  - this adjusts cumulative distance on adjacent point to new-calculated MIN,
                #          then heapifies it to maintain Priority Queue property!
                # ESSENTIALLY:  the ITERATIVE UPDATE of STATE before considering NEXT Unvisited Point by Cumulative Distance Priority
                unvisitedPriorityQ.decreaseKey(adjacentPt,
                                               nextAdjacentPtUpdatedCumDist)
示例#7
0
def CompareJson(alist):
    stack_container = []
    list_container = []
    container = PriorityQueue()
    container.buildHeap(alist)
    while container.currentSize > 0:
        stack_container.append(container.delMin())
    while len(list_container) < 10:
        list_container.append(stack_container.pop())
    return list_container
示例#8
0
def dijkstra(aGraph,start):
    pq = PriorityQueue()
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(),v) for v in aGraph])        
    while not pq.isEmpty():           currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():              newDist = currentVert.getDistance() \
                    + currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance():
                nextVert.setDistance( newDist )
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert,newDist)  
示例#9
0
def dijkstra(graph,start):
    start.setDistance(0)
    pq =PriorityQueue()    
    pq.buildHeap([(aVertex.getDistance(),aVertex) for aVertex in graph])
    while pq.size() > 0:
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newDist = currentVert.getDistance() + currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance():
                nextVert.setDistance(newDist)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert, newDist)
示例#10
0
def prim(agraph, start):
    pq = PriorityQueue()
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in agraph])
    while not pq.isEmpty():
        currentVert = pq.delMin()
        for nextvert in currentVert:
            # 仅考虑相邻点权重,即顶点到生成树集合的距离最短
            cost = currentVert(nextvert)
            if cost < nextvert.getDistance():
                nextvert.setDistance(cost)
                nextvert.setPred(currentVert)
                pq.decreaseKey(nextvert)
示例#11
0
def dijkstra(aGraph,start):
    pq = PriorityQueue()#建立一个优先队列
    start.setDistance(0)#起点的距离为0
    #建堆(堆排序,按距离从小到大排序),用元组记录每个点的距离,将所有点放入列表
    pq.buildHeap([(v.getDistance(),v) for v in aGraph])
    while not pq.isEmpty():#当队列有元素时
        currentVert = pq.delMin()#取出最小距离的点,设为当前节点
        for nextVert in currentVert.getConnections():#搜索当前节点的邻居
            #新距离=当前节点的距离+当前节点与该邻居的权重距离
            newDist = currentVert.getDistance()+currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance():#如果新距离小于原来记录的距离
                nextVert.setDistance(newDist)#将近距离记录下来
                nextVert.setPred(currentVert)#将当前节点设为父节点
                pq.decreaseKey(nextVert,newDist)#因为距离修改了,所以调整堆顺序
示例#12
0
def prim(graph, start):
    priorityQueue = PriorityQueue()
    start.setDistance(0)
    priorityQueue.buildHeap((v.getDistance(), v) for v in graph)
    while not priorityQueue.isEmpty():
        currentVert = priorityQueue.delMin()
        for neighborVert in currentVert.getConnections():
            distance = currentVert.getDistance() + currentVert.getWeight(
                neighborVert)
            if distance < neighborVert.getDistance(
            ) and neighborVert in priorityQueue:
                neighborVert.setDistance(distance)
                neighborVert.setPred(currentVert)
                priorityQueue.decreaseKey(neighborVert, distance)
示例#13
0
def dijkstra(a_graph, start):
    pq = PriorityQueue()
    start.distance = 0
    a_graph.append(start)
    pq.buildHeap([(v.distance, v) for v in a_graph])
    while not pq.isEmpty():
        current_vertex = pq.delMin()
        for next_vertex in current_vertex.connections:
            new_dist = current_vertex.distance \
                + current_vertex.distance_from(next_vertex)
            if new_dist < next_vertex.distance:
                next_vertex.distance = new_dist
                next_vertex.pred = current_vertex
                pq.decreaseKey(next_vertex, new_dist)
示例#14
0
def prim(G, start):
    pq = PriorityQueue()
    for v in G:
        v.setDistance(sys.maxsize)
        v.setPred(None)
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in G])
    while not pq.isEmpty():
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newCost = currentVert.getWeight(nextVert)
            if nextVert in pq and newCost < nextVert.getDistance():
                nextVert.setPred(currentVert)
                nextVert.setDistance(newCost)
                pq.decreaseKey(nextVert, newCost)
示例#15
0
def Diskistra(startVertex,Graph):
    pq=PriorityQueue()
    for vertex in Graph:
        vertex.setDistance(sys.maxsize)
        vertex.setPred(None)
    startVertex.setDistance(0)
    pq.buildHeap([(v.getDistance(),v) for v in Graph])
    while not pq.isEmpty():
        currentVertex=pq.delMin()
        for vertex in currentVertex.getConnections():
            newCost=currentVertex.getDistance()+currentVertex.getWeight(vertex)
            if newCost<vertex.getDistance():
                vertex.setDistance(newCost)
                vertex.setPred(currentVertex)
                pq.decreaseKey(vertex,newCost)
示例#16
0
文件: prim.py 项目: diccooo/py_algo
def prim(G, start):
    pq =PriorityQueue()
    for v in G:
        v.setDistance(sys.maxsize)
        v.setPred(None)
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in G])
    while not pq.isEmpty():
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newCost = currentVert.getDistance() + currentVert.getWeight(nextVert)
            if nextVert in pq and newCost < nextVert.getDistance():
                nextVert.setPred(currentVert)
                nextVert.setDistance(newCost)
                pq.decreaseKey(nextVert, newCost)
示例#17
0
def Diskistra(startVertex, Graph):
    pq = PriorityQueue()
    for vertex in Graph:
        vertex.setDistance(sys.maxsize)
        vertex.setPred(None)
    startVertex.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in Graph])
    while not pq.isEmpty():
        currentVertex = pq.delMin()
        for vertex in currentVertex.getConnections():
            newCost = currentVertex.getDistance() + currentVertex.getWeight(
                vertex)
            if newCost < vertex.getDistance():
                vertex.setDistance(newCost)
                vertex.setPred(currentVertex)
                pq.decreaseKey(vertex, newCost)
示例#18
0
 def Dijkstra(self, start):
     # initialize the heap with infinity dist
     pq = PriorityQueue()
     entries = dict([(str(v), float('inf')) for v in self.vertices])
     entries[str(start)] = 0
     pq.buildHeap([(float('inf'), v) for v in self.vertices])
     pq.decreaseKey(start, 0)
     # do the dijkstra step
     while not pq.isEmpty():
         cur = pq.delMin()
         for x in self.adj[cur]:
             dist = entries[str(cur)] + x[1]
             old = entries[str(x[0])]
             if old > dist:
                 entries[str(x[0])] = dist
                 pq.decreaseKey(x[0], dist)
     return entries
def dijkstra(aGraph, start):
    pq = PriorityQueue()
    start.setDistance(0)
    # initially the new costs to get them through the start node are their direct costs, so we update the costs to each of these nodes.
    # we also set the predecessor for each node to u and add each node to the priority queue.
    # we use the distance as the key for the priority queue.
    pq.buildHeap([(v.getDistance(), v) for v in aGraph])
    # we examine the vertices that are adjacent to x
    while not pq.isEmpty():
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newDist = currentVert.getDistance() \
                    + currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance():
                nextVert.setDistance(newDist)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert, newDist)
示例#20
0
 def dijkstra(self, start):
     if type(start) is not Vertex:
         for vert in self:
             if vert.id() == start:
                 start = vert
     start: Vertex
     pq = PriorityQueue()
     start.setDistance(0)
     pq.buildHeap([(v.distance(), v) for v in self])
     while not pq.isEmpty():
         currentVert = pq.delMin()
         for nextVert in currentVert.vertConnections():
             weight = min(
                 [x.weight() for x in self.edge(currentVert, nextVert)])
             newDist = currentVert.distance() + weight
             if newDist < nextVert.distance():
                 nextVert.setDistance(newDist)
                 nextVert.setPred(currentVert)
                 pq.decreaseKey(nextVert, newDist)
def buildGraph():
    g = Graph()

    #g.addEdge('u','v', 2)
    #g.addEdge('u','x', 1)
    #g.addEdge('v','w', 3)
    #g.addEdge('w','z', -5)
    #g.addEdge('u','w', 5)
    #g.addEdge('v','x', 2)
    #g.addEdge('x','y', 1)
    #g.addEdge('y','z', 1)
    #g.addEdge('x','w', 3)
    #g.addEdge('y','w', 1)

    #Fig 4.14 from S Dasgupta
    g.addEdge('s', 'a', 10)
    g.addEdge('s', 'g', 8)
    g.addEdge('g', 'f', 1)
    g.addEdge('a', 'e', 2)
    g.addEdge('f', 'a', -4)
    g.addEdge('f', 'e', -1)
    g.addEdge('e', 'b', -4)
    g.addEdge('b', 'a', 1)
    g.addEdge('b', 'c', 1)
    g.addEdge('c', 'd', 3)
    g.addEdge('d', 'e', -1)

    pq = PriorityQueue()

    start = g.getVertex('s')
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in g])
    while not pq.isEmpty():
        currentVert = pq.delMin()
        for nextVert in currentVert.getConnections():
            newDist = currentVert.getDistance() \
                    + currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance():
                nextVert.setDistance(newDist)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert, newDist)

    return g
示例#22
0
def prim(startVertex,Graph):
    pq=PriorityQueue()
    for vertex in Graph:
        vertex.setDistance(sys.maxsize)
        vertex.setPred(None)
    startVertex.setDistance(0)
    pq.buildHeap([(v.getDistance(),v) for v in Graph])
    while not pq.isEmpty():
        currentVertex=pq.delMin()
        pred=currentVertex.getPred()
        if pred:
            print ("( %s ,%s , %d)" % (currentVertex.getId(),pred.getId(),currentVertex.getDistance()))
        print currentVertex.getId(),
        for vertex in currentVertex.getConnections():
            newCost=currentVertex.getWeight(vertex)
            if newCost<vertex.getDistance():
                vertex.setDistance(newCost)
                vertex.setPred(currentVertex)
                pq.decreaseKey(vertex,newCost)
示例#23
0
def prim(startVertex, Graph):
    pq = PriorityQueue()
    for vertex in Graph:
        vertex.setDistance(sys.maxsize)
        vertex.setPred(None)
    startVertex.setDistance(0)
    pq.buildHeap([(v.getDistance(), v) for v in Graph])
    while not pq.isEmpty():
        currentVertex = pq.delMin()
        pred = currentVertex.getPred()
        if pred:
            print("( %s ,%s , %d)" % (currentVertex.getId(), pred.getId(),
                                      currentVertex.getDistance()))
        print currentVertex.getId(),
        for vertex in currentVertex.getConnections():
            newCost = currentVertex.getWeight(vertex)
            if newCost < vertex.getDistance():
                vertex.setDistance(newCost)
                vertex.setPred(currentVertex)
                pq.decreaseKey(vertex, newCost)
def prim(G,start):
    pq = PriorityQueue()
    for v in G:
    	# the distance to all the other vertices are initialized to infinity.
        v.setDistance(sys.maxsize)
        v.setPred(None)
    # we begin with the starting vertex as A for example
    start.setDistance(0)
    # we add initially the vertices which are the neighors of A to the priority queue
    pq.buildHeap([(v.getDistance(),v) for v in G])
    while not pq.isEmpty():
    	# look for the smallest distance
        currentVert = pq.delMin()
        # examine its neighbors 
        for nextVert in currentVert.getConnections():
        	# update the new distances
          	newCost = currentVert.getWeight(nextVert)
          	if nextVert in pq and newCost<nextVert.getDistance():
          		# set their predecessor links and new distance values
              	nextVert.setPred(currentVert)
              	nextVert.setDistance(newCost)
              	pq.decreaseKey(nextVert,newCost)
示例#25
0
def minimum_spanning_tree(graph, initial_city):
    start_city = graph.getVertex(initial_city)
    heap = PriorityQueue()
    aux_list = []
    solution = []
    visited_nodes = []

    new_graph = Graph()

    for conect in start_city.getConnections():
        aux_list.append(
            (start_city.getWeight(conect), (start_city.id, conect.id)))
        visited_nodes.append(start_city.id)

    heap.buildHeap(aux_list)

    while not heap.isEmpty():
        cur_pair = heap.delMin()
        cur_node = graph.getVertex(cur_pair[1])

        if cur_node.id not in visited_nodes:
            solution.append(cur_pair)
            visited_nodes.append(cur_node.id)
            for conect in cur_node.getConnections():
                if conect.id not in visited_nodes:
                    heap.add(
                        (cur_node.getWeight(conect), (cur_node.id, conect.id)))
        else:
            continue

    print('Solution: ' + str(solution))

    for city_1, city_2 in solution:
        new_graph.addEdge(city_1, city_2, 0)

    return new_graph
class OctTree:
    def __init__(self):
        self.root = None
        self.maxLevel = 5
        self.numLeaves = 0
        self.leafList = []
        self.leafQueue = PriorityQueue()
        self.image = None

    def openImage(self, imageFile):
        self.image = Image.open(imageFile)
        self.image.show()

    def writeImage(self, imageFile):
        self.image.save(imageFile)

    def buildTree(self):
        w, h = self.image.size
        for row in range(h):
            for col in range(w):
                r, g, b = self.image.getpixel((col, row))
                self.insert(r, g, b)

    def quantize(self, maxCubes, method="total"):
        self.reduce(maxCubes=maxCubes, method=method)
        w, h = self.image.size
        for row in range(h):
            for col in range(w):
                r, g, b = self.image.getpixel((col, row))
                nr, ng, nb = self.find(r, g, b)
                self.image.putpixel((col, row), (nr, ng, nb))
        self.image.show()

    def insert(self, r, g, b):
        if not self.root:
            self.root = self.otNode(outer=self)
        self.root.insert(r, g, b, 0, self)

    def find(self, r, g, b):
        if self.root:
            return self.root.find(r, g, b, 0)

    def reduce(self, maxCubes, method="total"):
        while len(self.leafList) > maxCubes:
            smallest = self.findMinCube(method)
            smallest.parent.merge()
            self.leafList.append(smallest.parent)
            self.leafQueue.add((smallest.parent.count, smallest.parent))
            self.numLeaves += 1

    def findMinCube(self, method="total"):
        if method != "individual":
            minCount = sys.maxsize
            maxLev = 0
            minCube = None
            i = self.leafQueue.delMin()
            minCube = i
            minCount = i.count
            maxLev = i.level
            self.leafQueue.add((i.count, i))
            #for i in self.leafList:
            #    if i.count <= minCount and i.level >= maxLev:
            #        minCube = i
            #        minCount = i.count
            #        maxLev = i.level
            return minCube
        else:
            tempDic = {}
            for i in self.leafList:
                if not i.parent in tempDic:
                    tempDic[i.parent] = i.count
                else:
                    tempDic[i.parent] += i.count
            minCount = sys.maxsize
            minKey = None
            for c in tempDic.keys():
                if tempDic[c] < minCount:
                    minCount = tempDic[c]
                    minKey = c
            for i in range(8):
                if minKey.children[i]:
                    return minKey.children[i]

    ####
    # Inner class otNode
    ####
    class otNode:
        def __init__(self, parent=None, level=0, outer=None):
            self.red = 0
            self.green = 0
            self.blue = 0
            self.count = 0
            self.parent = parent
            self.level = level
            self.oTree = outer
            self.children = [None] * 8

        def insert(self, r, g, b, level, outer):
            if level < self.oTree.maxLevel:
                idx = self.computeIndex(r, g, b, level)
                if self.children[idx] == None:
                    self.children[idx] = outer.otNode(parent = self, \
                                                      level = level + 1,\
                                                      outer = outer)
                self.children[idx].insert(r, g, b, level + 1, outer)
            else:
                if self.count == 0:
                    self.oTree.numLeaves += 1
                    self.oTree.leafList.append(self)
                    self.oTree.leafQueue.add((self.count, self))
                self.red += r
                self.green += g
                self.blue += b
                self.count += 1
                self.oTree.leafQueue.decreaseKey(self, self.count)

        def find(self, r, g, b, level):
            if level < self.oTree.maxLevel:
                idx = self.computeIndex(r, g, b, level)
                if self.children[idx]:
                    return self.children[idx].find(r, g, b, level + 1)
                elif self.count > 0:
                    return ((self.red // self.count, self.green // self.count,
                             self.blue // self.count))
                else:
                    raise KeyError("No leaf node for this color")
            else:
                return ((self.red // self.count, self.green // self.count,
                         self.blue // self.count))

        def merge(self):
            for i in self.children:
                if i:
                    if i.count > 0:
                        self.oTree.leafList.remove(i)
                        self.oTree.leafQueue.decreaseKey(i, -1 * (sys.maxsize))
                        self.oTree.leafQueue.delMin()
                        self.oTree.numLeaves -= 1
                    else:
                        print("Recursively Merging non-leaf...")
                        i.merge()
                    self.count += i.count
                    self.red += i.red
                    self.green += i.green
                    self.blue += i.blue
            for i in range(8):
                self.children[i] = None

        def computeIndex(self, r, g, b, level):
            shift = 8 - level
            rc = (r >> (shift - 2)) & 0x4
            gc = (g >> (shift - 1)) & 0x2
            bc = (b >> (shift)) & 0x1
            return (rc | gc | bc)