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)
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()
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
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