Exemple #1
0
def computeeffort(pathgraph, optoneorder, x_init, y_init, x_end, y_end):
    totaleffort = 0
    totalweight = 0
    count = 0
    distemp = 0
    for id in optoneorder:
        if id not in iteminfo_dict:
            print("no dimension information of such item id:", id,
                  "set default weight 0.1")
            iteminfo_dict[id] = {}
            iteminfo_dict[id]['weight'] = 0.1

        if count == 0:
            distemp, x_des, y_des = findpath(pathgraph, id, x_init, y_init)
            x_init = x_des
            y_init = y_des
            totalweight = totalweight + iteminfo_dict[id]['weight']
            count = count + 1
            continue

        distemp, x_des, y_des = findpath(pathgraph, id, x_init, y_init)
        totaleffort = totaleffort + distemp * totalweight

        totalweight = totalweight + iteminfo_dict[id]['weight']
        x_init = x_des
        y_init = y_des
        count = count + 1

    distemp, temp = graphtest.locdistance(pathgraph, x_end, y_end, x_init,
                                          y_init)

    totaleffort = totaleffort + distemp * totalweight

    print("total effort", round(totaleffort, 1))
    return round(totaleffort, 1)
Exemple #2
0
def findpath(pathgraph, pro_id, init_x=0, init_y=0):
    pro_id = int(pro_id)

    if pro_id not in loc_dict:
        print("id not exist")
        return -1

    pro_x = loc_dict[pro_id][0]  #x,y coordinates of products
    pro_y = loc_dict[pro_id][1]
    # print "Searching product id",pro_id, "product position", (pro_x,pro_y)
    # print "Calculating shortest path for one item......"

    #Product con only be taken from left or right, say east and west
    #if the product position is east to the current position i.e. init_x < prod_x
    if init_x < pro_x:
        des_x = pro_x - 1  #shorter to take from left path of the rack
        des_y = pro_y
        # if pro_x == 0:
        #     des_x = pro_x + 1 #can only take from right since its the boundary, say wall
        #     des_y = pro_y
    #if the product position is west to the current position i.e. init_x > prod_x
    elif init_x > pro_x:
        des_x = pro_x + 1  #shorter to take from right path of the rack
        des_y = pro_y
        # if pro_x == 20:
        #     des_x = pro_x - 1 #can only take from left since its the boundary, say wall
        #     des_y = pro_y
    else:
        des_x = init_x
        des_y = pro_y
    itemdistance, traversed = graphtest.locdistance(pathgraph, des_x, des_y,
                                                    init_x, init_y)
    return itemdistance, des_x, des_y
def originalorder(oneorder, x_init, y_init, x_end, y_end):
    # original order
    dist_oneorder = 0
    for item in oneorder:
        dist, x_des, y_des = findpath(item, x_init, y_init)
        x_init = x_des
        y_init = y_des
        dist_oneorder = dist_oneorder + dist
        # print
    # back to end point

    # print"returning to end point......"
    backtrip = graphtest.locdistance(pathgraph, x_init, y_init, x_end, y_end)
    dist_oneorder = dist_oneorder + backtrip

    print('Distance for one order without optimization', dist_oneorder)
    return dist_oneorder
    def route_in_batch(self):

        ax3 = self.figure.add_subplot(111)
        axes3 = plt.gca()
        axes3.set_ylim([-1, 21])
        axes3.set_xlim([-1, 41])
        ax3.set_title(
            'Draw optimized route according to order number in csv file')
        opt = self.optorder
        x_temp = self.x_init
        y_temp = self.y_init
        for item in opt:
            if item not in loc_dict:
                print("id not exist")
                return -1

            pro_x = loc_dict[item][0]  # x,y coordinates of products
            pro_y = loc_dict[item][1]
            if self.x_init < pro_x:
                des_x = pro_x - 1  # shorter to take from left path of the rack
                des_y = pro_y
                # if pro_x == 0:
                #     des_x = pro_x + 1 #can only take from right since its the boundary, say wall
                #     des_y = pro_y
            # if the product position is west to the current position i.e. init_x > prod_x
            elif self.x_init > pro_x:
                des_x = pro_x + 1  # shorter to take from right path of the rack
                des_y = pro_y
                # if pro_x == 20:
                #     des_x = pro_x - 1 #can only take from left since its the boundary, say wall
                #     des_y = pro_y
            else:
                des_x = self.x_init
                des_y = pro_y
            min, traversedpoint = locdistance(pathgraph, des_x, des_y,
                                              self.x_init, self.y_init)
            data = np.array(traversedpoint)
            plt.plot(data[:, 0], data[:, 1])
            self.x_init = des_x
            self.y_init = des_y
        min, traversedpoint = locdistance(pathgraph, self.x_end, self.y_end,
                                          self.x_init,
                                          self.y_init)  #to end point
        data = np.array(traversedpoint)
        plt.plot(data[:, 0], data[:, 1])
        self.x_init = x_temp
        self.y_init = y_temp

        #draw order path

        # data = np.array([[1, 2], [2, 4], [3, 5], [4, 5]])
        # plt.plot(data[:, 0], data[:, 1])

        # B = nx.Graph()
        # B.add_nodes_from([1, 2, 3, 4], bipartite=0)
        # B.add_nodes_from(['a', 'b', 'c', 'd', 'e'], bipartite=1)
        # B.add_edges_from([(1, 'a'), (2, 'c'), (3, 'd'), (3, 'e'), (4, 'e'), (4, 'd')])
        #
        # X = set(n for n, d in B.nodes(data=True) if d['bipartite'] == 0)
        # Y = set(B) - X
        #
        # X = sorted(X, reverse=True)
        # Y = sorted(Y, reverse=True)
        #
        # pos = dict()
        # pos.update((n, (1, i)) for i, n in enumerate(X))  # put nodes from X at x=1
        # pos.update((n, (2, i)) for i, n in enumerate(Y))  # put nodes from Y at x=2
        # nx.draw(B, pos=pos, with_labels=True)
        self.canvas.draw_idle()
    def Routing(self):  #

        ax2 = self.figure.add_subplot(111)
        axes2 = plt.gca()
        axes2.set_ylim([-1, 21])
        axes2.set_xlim([-1, 41])
        ax2.set_title('Routing')
        #process one order
        if self.oneorder == [] or self.x_init == None or self.y_init == None or self.x_end == None or self.y_init == None:
            self.x_init = 0
            self.y_init = 0
            self.x_end = 0
            self.y_end = 20
            self.oneorder = [181202, 328595, 276157, 296188, 8140,
                             208299]  #[1,45,74]
        x_temp = self.x_init
        y_temp = self.y_init
        oneorder = []
        for elem in self.oneorder:
            oneorder.append(int(elem))

        org, origl, opt, min = singleOrder(pathgraph, oneorder, self.x_init,
                                           self.y_init, self.x_end,
                                           self.y_init)
        print(org, opt)
        for item in opt:
            if item not in loc_dict:
                print("id not exist")
                return -1

            pro_x = loc_dict[item][0]  # x,y coordinates of products
            pro_y = loc_dict[item][1]
            if self.x_init < pro_x:
                des_x = pro_x - 1  # shorter to take from left path of the rack
                des_y = pro_y
                # if pro_x == 0:
                #     des_x = pro_x + 1 #can only take from right since its the boundary, say wall
                #     des_y = pro_y
            # if the product position is west to the current position i.e. init_x > prod_x
            elif self.x_init > pro_x:
                des_x = pro_x + 1  # shorter to take from right path of the rack
                des_y = pro_y
                # if pro_x == 20:
                #     des_x = pro_x - 1 #can only take from left since its the boundary, say wall
                #     des_y = pro_y
            else:
                des_x = self.x_init
                des_y = pro_y
            min, traversedpoint = locdistance(pathgraph, des_x, des_y,
                                              self.x_init, self.y_init)
            data = np.array(traversedpoint)
            plt.plot(data[:, 0], data[:, 1])
            self.x_init = des_x
            self.y_init = des_y
        min, traversedpoint = locdistance(pathgraph, self.x_end, self.y_end,
                                          self.x_init,
                                          self.y_init)  #to end point
        data = np.array(traversedpoint)
        plt.plot(data[:, 0], data[:, 1])
        self.x_init = x_temp
        self.y_init = y_temp

        #draw order path

        self.canvas.draw_idle()
Exemple #6
0
def branchnbound(pathgraph, oneorder, init_x, init_y, end_x, end_y):
    # construct graph and distance dictionary between graph
    ordergraph = nx.Graph()
    optoneorder = []
    matrix = [[inf]]
    redumatrix = []
    subcost = 0
    ordergraph.add_node('start', pos=(init_x, init_y))
    ordergraph.add_node('end', pos=(end_x, end_y))

    for item_no in oneorder:
        ordergraph.add_node(item_no,
                            pos=(loc_dict[item_no][0], loc_dict[item_no][1]))
        # calculate from these item to end or from original to these item
        d0, des_x, des_y = findpath(pathgraph, item_no, init_x,
                                    init_y)  # from original is 'start'
        dist_dict[('start', item_no)] = d0
        df, traversed = graphtest.locdistance(pathgraph, end_x, end_y, des_x,
                                              des_y)  # to end
        dist_dict[(item_no, 'end')] = df
        ordergraph.add_edge('start', item_no, weight=d0)
        ordergraph.add_edge('end', item_no, weight=df)
        matrix[0].append(d0)  #source to distination  horizontal add
        matrix.append([d0])  #vertical add

    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    i = 1
    for item in oneorder:
        for another in oneorder:
            if another == item:
                matrix[i].append(inf)
                continue
            pro_x1 = loc_dict[another][0]  # x,y coordinates of products
            pro_y1 = loc_dict[another][1]
            pro_x2 = loc_dict[item][0]  # x,y coordinates of products
            pro_y2 = loc_dict[item][1]
            pathlength = graphtest.locdistance(pathgraph, pro_x2 - 1, pro_y2,
                                               pro_x1 - 1, pro_y1)
            ordergraph.add_edge(item, another, weight=pathlength[0])
            matrix[i].append(pathlength[0])
        i = i + 1
    # print('Original distance')
    # for row in matrix:
    #     print(row)
    start = time.time()
    print("Computing shortest distance to travel using branch and bound......")

    # algorithm begins here-----------------------------------------------------------------------------------------
    # priority queue for min cost value node using heapq
    level = 0
    nodenum = 0
    itemcurr = None
    pathtemp = []

    # initial reduce from starting point
    redumatrix, initcost = matrixredu(matrix)
    # add root node to dict
    treenode_dict[nodenum] = [
        initcost, deepcopy(redumatrix), level, 0, None, []
    ]  #root node cost,matrix,number visited,current item,path
    print("initial matrix")
    for row in matrix:
        print(row)
    print("initial cost", initcost)
    # # calculate from start to other node:
    while len(treenode_dict) != 0:
        minnode = min(treenode_dict, key=lambda k: treenode_dict[k])

        #modify min cost key to be the largest level if several same costs occurred in diff level
        costtemp = treenode_dict[minnode][0]
        leveltemp = 0
        for item in treenode_dict:
            if treenode_dict[item][0] == costtemp:
                if treenode_dict[item][2] > leveltemp:
                    leveltemp = treenode_dict[item][2]
                    minnode = item

        itemcurr = treenode_dict[minnode][3]
        level = treenode_dict[minnode][2]
        # matrixtemp=deepcopy(treenode_dict[minnode][1])
        pathtemp = deepcopy(treenode_dict[minnode][5])
        pathtemp.append(itemcurr)

        #     redumatrixtemp, optchoice, cost = reduroutine(redumatrix, src, oneordertemptemp, oneorder, initcost, optoneordertemp)

        for des in range(len(oneorder) + 1):
            # if des in pathtemp:
            #     continue# pass if traversed in current path
            if treenode_dict[minnode][1][itemcurr][
                    des] != inf and des not in pathtemp:
                print('new node ', nodenum + 1,
                      '----------------------------------------')
                nodenum = nodenum + 1
                #set row and col

                redumatrixtemp = deepcopy(redumatrix)
                redumatrixtemp[itemcurr] = [inf] * len(
                    redumatrixtemp)  #set source row to inf
                for i in range(len(redumatrixtemp)):
                    redumatrixtemp[i][des] = inf  #set des col to inf

                redumatrixtemp[des][0] = inf  #set dest->src to inf

                # print("child to be reduced")
                # for row in redumatrixtemp:
                #     print(row)
                # #reduce child matrix
                redumatrixchild, costchild = matrixredu(
                    deepcopy(redumatrixtemp))
                # print("child reduced")
                #
                # for row in redumatrixchild:
                #     print(row)
                # print("child cost", costchild)

                print("path before:", pathtemp)
                costtemp = treenode_dict[minnode][0] + treenode_dict[minnode][
                    1][itemcurr][des] + costchild  #child->redumatrix
                treenode_dict[nodenum] = [
                    costtemp,
                    deepcopy(redumatrixtemp), level + 1, des,
                    treenode_dict[minnode][3],
                    deepcopy(pathtemp)
                ]
                print("cost:", costtemp, "parent:", itemcurr, "parent node:",
                      minnode, "child", des, "level", level + 1)

        if treenode_dict[nodenum][2] == len(
                oneorder):  #if all items reached return mincost

            end = time.time()
            print("branch and bound cost:", end - start)
            # pathtemp.append(treenode_dict[minlastcost][3])
            # minlastcost=min(treenode_dict, key=lambda k: treenode_dict[k])
            print("Shortest path:", treenode_dict[nodenum][5], "Last node:",
                  treenode_dict[nodenum][3], "its parent:",
                  treenode_dict[nodenum][4])
            print("upper bound:", treenode_dict[nodenum][0])
            print("final matrix")
            for row in treenode_dict[nodenum][1]:
                print(row)
            pathtemp.append(treenode_dict[nodenum][3])
            pathtemp.pop(0)
            for item in pathtemp:
                optoneorder.append(oneorder[item - 1])

            mindist = treenode_dict[nodenum][0]  #!!!!!!!!!!!!!!!!!!!
            # print out path
            print('Minimum travel distance: ', mindist, ',in order of: ',
                  'start from ', (init_x, init_y), optoneorder, ', end at ',
                  (end_x, end_y))

            for item in optoneorder:
                print(
                    'go to shelf:',
                    shelf_dict[item],
                    'on location:',
                    loc_dict[item],
                    'pick up item:',
                    item,
                    ', then ',
                )
            # measure time

            print('drop off at:', [end_x, end_y])
            print('Branch and bound cost:', end - start)

            return optoneorder, mindist

            # return treenode_dict[minnode][],treenode_dict[minnode][0]

        del treenode_dict[minnode]
        del minnode
Exemple #7
0
def optimizeorder(pathgraph, oneorder, init_x, init_y, end_x, end_y):
    # construct graph and distance dictionary between graph
    ordergraph = nx.Graph()
    optoneorder = []
    # orderloc = []
    ordergraph.add_node('start', pos=(init_x, init_y))
    ordergraph.add_node('end', pos=(end_x, end_y))

    for item_no in oneorder:
        ordergraph.add_node(item_no,
                            pos=(loc_dict[item_no][0], loc_dict[item_no][1]))
        # orderloc.append(loc_dict[item_no])
        # calculate from these item to end or from original to these item
        d0, des_x, des_y = findpath(pathgraph, item_no, init_x,
                                    init_y)  #from original is 'start'
        dist_dict[('start', item_no)] = d0
        df, traversed = graphtest.locdistance(pathgraph, end_x, end_y, des_x,
                                              des_y)  #to end
        dist_dict[(item_no, 'end')] = df
        ordergraph.add_edge('start', item_no, weight=d0)
        ordergraph.add_edge('end', item_no, weight=df)
    '''
    # Dynamic programming
    print("Dynamic programming shortest distance to travel ......")

    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    for pair in nodespair:
        d, des_x, des_y = findpath(pair[0])
        pathlength, x, y = findpath(pair[1], des_x, des_y)
        # add graph edge
        ordergraph.add_edge(pair[0], pair[1], length=pathlength)
        dist_dict[(pair[0], pair[1])] = pathlength
        dist_dict[(pair[1], pair[0])] = pathlength

    # solving dsp problem recursively
    start = time.time()

    min,optoneorder= shortestdp('start',oneorder)



    print('Minimum travel distance: ', min, ',in order of: ', 'start from ', (init_x, init_y), optoneorder, ', end at ',
          (end_x, end_y))
    loclist = []
    for item in optoneorder:
        print('go to shelf:', shelf_dict[item], 'on location:', loc_dict[item], 'pick up item:', item, ', then ', )
    # measure time
    end = time.time()
    print('drop off at:', [end_x, end_y])
    print('Dynamic programming cost:', end - start)

    '''
    '''
    #debug use, calculate lower bound print minimum spanning tree
    if __debug__:
        print("Calculating lower bound......")
        nodespair = list(itertools.combinations(oneorder, 2))

        # heuristics,not known:start from nowhere? distance between 2 items,+-1
        for pair in nodespair:
            pro_x = loc_dict[pair[0]][0]  # x,y coordinates of products
            pro_y = loc_dict[pair[0]][1]
            pathlength, xtmp, ytmp = findpath(pathgraph,pair[1],pro_x-1,pro_y)
            # add graph edge
            ordergraph.add_edge(pair[0], pair[1], weight=pathlength)
        print (ordergraph.edges(data=True))
        pos = nx.get_node_attributes(ordergraph, 'pos')
        nx.draw_networkx(ordergraph,pos)
        labels = nx.get_edge_attributes(ordergraph, 'weight')
        nx.draw_networkx_edge_labels(ordergraph, pos, edge_labels=labels)
        plt.show(block=False)
        time.sleep(5)
        plt.close()
        T = nx.minimum_spanning_tree(ordergraph)
        print(T.edges(data=True))
        pos = nx.get_node_attributes(T, 'pos')
        nx.draw_networkx(T, pos)
        labels = nx.get_edge_attributes(T, 'weight')
        nx.draw_networkx_edge_labels(T, pos, edge_labels=labels)
        plt.show()

    '''
    # nearest neighbor
    print("Computing greedily shortest distance to travel ......")
    start = time.time()
    # nodespair = list(itertools.combinations(oneorder, 2))
    # ordergraph.add_edges_from(nodespair)
    # # heuristics,not known:start from nowhere? distance between 2 items,+-1
    # for pair in nodespair:
    #     d, des_x, des_y = findpath(pair[0])
    #     pathlength, x, y = findpath(pair[1], des_x, des_y)
    #     # add graph edge
    #     ordergraph.add_edge(pair[0], pair[1], length=pathlength)
    #     dist_dict[(pair[0], pair[1])] = pathlength
    #     dist_dict[(pair[1], pair[0])] = pathlength

    itemtemp = 0

    x = init_x
    y = init_y
    temp_x = None
    temp_y = None
    itemshift = 0
    oneordertemp = []
    optoneordertemp = []
    mindist = 10000
    init_x_l = 0
    init_y_l = 0
    for i in range(len(oneorder) - 1):
        itemshift = oneorder.pop(0)
        oneorder.append(itemshift)
        oneordertemp = oneorder[:]
        print("after shift:", oneorder)
        mindisttemp = 0
        while oneorder != []:
            min = 10000
            for item in oneorder:
                pathlength, des_x, des_y = findpath(pathgraph, item, x, y)

                if pathlength < min:
                    min = pathlength
                    itemtemp = item
                    temp_x = des_x
                    temp_y = des_y

            optoneordertemp.append(itemtemp)
            oneorder.remove(itemtemp)
            mindisttemp = mindisttemp + min
            x = temp_x
            y = temp_y
        mindisttemp = mindisttemp + graphtest.locdistance(
            pathgraph, end_x, end_y, x, y)[0]  #to drop off point
        print("mindist:", mindisttemp)
        print("one optimized:", optoneordertemp)
        if mindisttemp < mindist:
            mindist = mindisttemp
            init_x_l = x
            init_y_l = y
            optoneorder = optoneordertemp[:]

        oneorder = oneordertemp[:]
        optoneordertemp = []
        oneordertemp = []
        x = init_x
        y = init_y

    print('Minimum travel distance: ', mindist, ',in order of: ',
          'start from ', (init_x, init_y), optoneorder, ', end at ',
          (end_x, end_y))

    for item in optoneorder:
        print(
            'go to shelf:',
            shelf_dict[item],
            'on location:',
            loc_dict[item],
            'pick up item:',
            item,
            ', then ',
        )
    # measure time
    end = time.time()
    print('drop off at:', [end_x, end_y])
    print('Nearest neighbor cost:', end - start)
    min = mindist
    '''
    # brute force compute optimized order
    print ("Computing brute force shortest distance to travel ......")

    start = time.time()
    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    for pair in nodespair:
        d,des_x,des_y = findpath(pair[0])
        pathlength,x,y= findpath(pair[1],des_x,des_y)
        # add graph edge
        ordergraph.add_edge(pair[0], pair[1], length = pathlength)
        dist_dict[(pair[0], pair[1])] = pathlength
        dist_dict[(pair[1], pair[0])] = pathlength
        # print "shortest distance between ",(pair[0], pair[1])," ",pathlength
    # print dist_dict
    # distances between pairs calculated, brute force calculate shortest travelling order
    # brute force
    possiblepath = list(itertools.permutations(oneorder))
    # print 'possible path: ', possiblepath
    min = 1000000
    dist = 0

    for p in possiblepath:
        for item in range(len(p)-1):
            if item == 0:
                dist = dist_dict[('start',p[item])]# distance from start to first product
            dist = dist+dist_dict[(p[item], p[item+1])]
            # print (p[item], p[item+1])
        dist = dist + dist_dict[(p[item+1], 'end')]#distance to drop off point
        if dist< min:
            min = dist
            optoneorder = list(p)
        dist = 0
    print ('Minimum travel distance: ',min,',in order of: ', 'start from ',(init_x,init_y),optoneorder,', end at ',(end_x,end_y))
    loclist = []
    for item in optoneorder:
        print( 'go to shelf:',shelf_dict[item],'on location:', loc_dict[item], 'pick up item:',item, ', then ',)
    # measure time
    end = time.time()
    print ('drop off at:', [end_x,end_y])
    print('Brute force cost:', end - start)
    '''
    return optoneorder, min
def optimizeorder(oneorder, init_x, init_y, end_x, end_y):
    # construct graph and distance dictionary between graph
    ordergraph = nx.Graph()
    optoneorder = []
    orderloc = []
    ordergraph.add_node('start')
    ordergraph.add_node('end')
    for item_no in oneorder:
        orderloc.append(loc_dict[item_no])
        ordergraph.add_node(item_no)

        # calculate from these item to end or from original to these item
        d0, des_x, des_y = findpath(item_no, init_x,
                                    init_y)  #from original is 'start'
        dist_dict[('start', item_no)] = d0
        df = graphtest.locdistance(pathgraph, end_x, end_y, des_x,
                                   des_y)  #to end
        dist_dict[(item_no, 'end')] = df
        ordergraph.add_edge('start', item_no, length=d0)
        ordergraph.add_edge('end', item_no, length=df)

    # Dynamic programming
    print("Dynamic programming shortest distance to travel ......")

    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    for pair in nodespair:
        d, des_x, des_y = findpath(pair[0])
        pathlength, x, y = findpath(pair[1], des_x, des_y)
        # add graph edge
        ordergraph.add_edge(pair[0], pair[1], length=pathlength)
        dist_dict[(pair[0], pair[1])] = pathlength
        dist_dict[(pair[1], pair[0])] = pathlength

    # solving dsp problem recursively
    start = time.time()

    min, optoneorder = shortestdp('start', oneorder)

    print('Minimum travel distance: ', min, ',in order of: ', 'start from ',
          (init_x, init_y), optoneorder, ', end at ', (end_x, end_y))
    loclist = []
    for item in optoneorder:
        print(
            'go to shelf:',
            shelf_dict[item],
            'on location:',
            loc_dict[item],
            'pick up item:',
            item,
            ', then ',
        )
    # measure time
    end = time.time()
    print('drop off at:', [end_x, end_y])
    print('Dynamic programming cost:', end - start)
    '''
    # nearest neighbor
    print("Computing greedily shortest distance to travel ......")
    start = time.time()
    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    for pair in nodespair:
        d, des_x, des_y = findpath(pair[0])
        pathlength, x, y = findpath(pair[1], des_x, des_y)
        # add graph edge
        ordergraph.add_edge(pair[0], pair[1], length=pathlength)
        dist_dict[(pair[0], pair[1])] = pathlength
        dist_dict[(pair[1], pair[0])] = pathlength
    firstitem = 'start'
    itemtemp = 0
    mindist = 0
    while oneorder !=[]:
        min = 10000
        for item in oneorder:
            if dist_dict[(firstitem,item)]<min:
                min = dist_dict[(firstitem,item)]
                itemtemp = item
        firstitem=itemtemp
        optoneorder.append(firstitem)
        oneorder.remove(firstitem)
        mindist = mindist + min
    mindist = mindist + dist_dict[(firstitem,'end')]#to drop off point

    print('Minimum travel distance: ', mindist, ',in order of: ', 'start from ', (init_x, init_y), optoneorder, ', end at ',
          (end_x, end_y))
    loclist = []
    for item in optoneorder:
        print('go to shelf:', shelf_dict[item], 'on location:', loc_dict[item], 'pick up item:', item, ', then ', )
    # measure time
    end = time.time()
    print('drop off at:', [end_x, end_y])
    print('Nearest neighbor cost:', end - start)
    min = mindist
    '''
    '''
    # brute force compute optimized order
    print ("Computing brute force shortest distance to travel ......")

    start = time.time()
    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    for pair in nodespair:
        d,des_x,des_y = findpath(pair[0])
        pathlength,x,y= findpath(pair[1],des_x,des_y)
        # add graph edge
        ordergraph.add_edge(pair[0], pair[1], length = pathlength)
        dist_dict[(pair[0], pair[1])] = pathlength
        dist_dict[(pair[1], pair[0])] = pathlength
        # print "shortest distance between ",(pair[0], pair[1])," ",pathlength
    # print dist_dict
    # distances between pairs calculated, brute force calculate shortest travelling order
    # brute force
    possiblepath = list(itertools.permutations(oneorder))
    # print 'possible path: ', possiblepath
    min = 1000000
    dist = 0

    for p in possiblepath:
        for item in range(len(p)-1):
            if item == 0:
                dist = dist_dict[('start',p[item])]# distance from start to first product
            dist = dist+dist_dict[(p[item], p[item+1])]
            # print (p[item], p[item+1])
        dist = dist + dist_dict[(p[item+1], 'end')]#distance to drop off point
        if dist< min:
            min = dist
            optoneorder = list(p)
        dist = 0
    print ('Minimum travel distance: ',min,',in order of: ', 'start from ',(init_x,init_y),optoneorder,', end at ',(end_x,end_y))
    loclist = []
    for item in optoneorder:
        print( 'go to shelf:',shelf_dict[item],'on location:', loc_dict[item], 'pick up item:',item, ', then ',)
    # measure time
    end = time.time()
    print ('drop off at:', [end_x,end_y])
    print('Brute force cost:', end - start)
    '''
    return optoneorder, min
def branchnbound(pathgraph, oneorder, init_x, init_y, end_x, end_y):
    # construct graph and distance dictionary between graph
    ordergraph = nx.Graph()
    optoneorder = []
    matrix = [[None]]
    redumatrix = []
    subcost = 0
    ordergraph.add_node('start', pos=(init_x, init_y))
    ordergraph.add_node('end', pos=(end_x, end_y))

    for item_no in oneorder:
        ordergraph.add_node(item_no,
                            pos=(loc_dict[item_no][0], loc_dict[item_no][1]))
        # calculate from these item to end or from original to these item
        d0, des_x, des_y = findpath(pathgraph, item_no, init_x,
                                    init_y)  # from original is 'start'
        dist_dict[('start', item_no)] = d0
        df, traversed = graphtest.locdistance(pathgraph, end_x, end_y, des_x,
                                              des_y)  # to end
        dist_dict[(item_no, 'end')] = df
        ordergraph.add_edge('start', item_no, weight=d0)
        ordergraph.add_edge('end', item_no, weight=df)
        matrix[0].append(d0)  #source to distination  horizontal add
        matrix.append([d0])  #vertical add

    start = time.time()
    nodespair = list(itertools.combinations(oneorder, 2))
    ordergraph.add_edges_from(nodespair)
    # heuristics,not known:start from nowhere? distance between 2 items,+-1
    i = 1
    for item in oneorder:
        for another in oneorder:
            if another == item:
                matrix[i].append(None)
                continue
            pro_x1 = loc_dict[another][0]  # x,y coordinates of products
            pro_y1 = loc_dict[another][1]
            pro_x2 = loc_dict[item][0]  # x,y coordinates of products
            pro_y2 = loc_dict[item][1]
            pathlength = graphtest.locdistance(pathgraph, pro_x2 - 1, pro_y2,
                                               pro_x1 - 1, pro_y1)
            ordergraph.add_edge(item, another, weight=pathlength[0])
            matrix[i].append(pathlength[0])
        i = i + 1
    for row in matrix:
        print(row)
    print("Computing shortest distance to travel using branch and bound......")

    # algorithm begins here-----------------------------------------------------------------------------------------
    # initial reduce from starting point
    redumatrix, initcost = matrixredu(matrix)

    # print("initial reduced")
    # for row in redumatrix:
    #     print(row)
    # calculate from start to other node:
    src = 0
    oneordertemp = oneorder[:]
    optoneordertemp = []
    oneordertemptemp = oneordertemp[:]
    while len(oneordertemp) != 1:
        redumatrixtemp, optchoice, cost = reduroutine(redumatrix, src,
                                                      oneordertemptemp,
                                                      oneorder, initcost,
                                                      optoneordertemp)

        #WAY 2
        '''
        hassmaller=False
        mincosttemp=cost
        for item in range(1,len(oneorder)+1):
            if item not in [i[0] for i in matrix_dict.keys()]:
                continue
            layer=max([i[1] for i in matrix_dict.keys() if i[0] == item])#get the largest layer which according to certain key
            if matrix_dict[(item,layer)][0] < mincosttemp and layer is not 0:
                hassmaller=True
                mincosttemp=matrix_dict[(item,layer)][0]
                itemtemp=item
                layertemp=layer



        # for itemcost in [row[0] for row in matrix_dict.values()]:
        #     if itemcost <cost:
        #         minindex = [row[0] for row in matrix_dict.values()].index(itemcost)
        #         print('minindex',minindex)
        #         (destmintemp, layertemp) = list(matrix_dict.keys())[minindex]
        #         if oneorder[destmintemp - 1] not in optoneorder:  # only bounce back when dest not traversed(not parent)
        #             if layertemp is not 0:#layertemp < len(optoneorder)-1 and
        #                 hassmaller=True
        #                 if itemcost<itemcosttemp:
        #                     itemcosttemp=itemcost
        #                     (destmin, layer) = list(matrix_dict.keys())[minindex]

        if hassmaller is True:
            oneordertemp = matrix_dict[(itemtemp, layertemp)][2][:]
            oneordertemp.append(oneorder[itemtemp - 1])  # add opt this time but not excatly opt
            src = itemtemp
            redumatrix = [row[:] for row in matrix_dict[(itemtemp, layertemp)][1]]
            if len([i for i in redumatrix[src] if i is not None])==0 and src == itemtemp:
                hassmaller=False
            initcost = matrix_dict[(itemtemp, layertemp)][0]
            optoneorder = matrix_dict[(itemtemp, layertemp)][3][:]
            del matrix_dict[(itemtemp,layertemp)]
            optoneordertemp = optoneorder[:]
            oneordertemptemp = oneordertemp[:]
        if hassmaller is False:
            redumatrix = [row[:] for row in redumatrixtemp]  # go down the tree if indeed smallest
            # print('optchorce',optchoice)
            src = optchoice
            initcost = cost
            # print('normal opt:', oneorder[optchoice - 1])
            del matrix_dict[(src,len(optoneorder))]
            optoneorder.append(oneorder[optchoice - 1])
            optoneordertemp=optoneorder[:]
            oneordertemp.remove(oneorder[optchoice - 1])
            oneordertemptemp=oneordertemp[:]

            # print('opt order',oneorder[optchoice-1])
        print('OPT TILL NOW', optoneorder)

        '''#WAY 1 SECCEED
        # get the minimum of dict
        if min([row[0] for row in matrix_dict.values()]) < cost:
            minindex = [row[0] for row in matrix_dict.values()
                        ].index(min([row[0] for row in matrix_dict.values()]))
            # print('minindex',list(matrix_dict.keys()))
            (destmin, srcmin) = list(matrix_dict.keys())[minindex]
            if oneorder[
                    destmin -
                    1] not in optoneorder:  # only bounce back when dest not traversed(not parent)
                oneordertemp = matrix_dict[minindex][2][:]  # *= all dest
                src = destmin
                redumatrix = [row[:] for row in matrix_dict[minindex][1]]
                initcost = matrix_dict[minindex][0]
                optoneorder = matrix_dict[minindex][3][:]
            else:
                redumatrix = [
                    row[:] for row in redumatrixtemp
                ]  # go down the tree if indeed smallest same as normal
                # print('optchorce',optchoice)
                src = optchoice
                initcost = cost
                optoneorder.append(oneorder[optchoice - 1])
                oneordertemp.remove(oneorder[optchoice - 1])
        else:
            redumatrix = [row[:] for row in redumatrixtemp
                          ]  # go down the tree if indeed smallest
            # print('optchorce',optchoice)
            src = optchoice
            initcost = cost
            print('normal opt:', oneorder[optchoice - 1])
            optoneorder.append(oneorder[optchoice - 1])
            oneordertemp.remove(oneorder[optchoice - 1])
            # print('opt order',oneorder[optchoice-1])

    mindist = cost

    optoneorder.append(oneordertemp[0])
    # oneorder=oneordertemp[:]

    # algorithm ends here---------------------------------

    print('Minimum travel distance: ', mindist, ',in order of: ',
          'start from ', (init_x, init_y), optoneorder, ', end at ',
          (end_x, end_y))

    for item in optoneorder:
        print(
            'go to shelf:',
            shelf_dict[item],
            'on location:',
            loc_dict[item],
            'pick up item:',
            item,
            ', then ',
        )
    # measure time
    end = time.time()
    print('drop off at:', [end_x, end_y])
    print('Branch and bound cost:', end - start)

    return optoneorder, mindist