def genInitialSolutionIFulosuyHybridBalanced(self, rule='MaxDepo'): ''' Generate initial solution using a specific predefined rule ''' reqArc = self.info.reqArcList collectFlag = {} solutionKeys = ['Load', 'Cost', 'Solution'] for i in reqArc: collectFlag[i] = False unserviced = dictFind.Lookup(collectFlag) vehicleNumber = 0 totalCost = 0 solutionDict = {} while unserviced: vehicleNumber = vehicleNumber + 1 (Cost, Load, Sequence, collectFlag) = self.singleRouteIFulosoyHybridBalanced( rule, collectFlag) look = dictFind.Lookup(collectFlag) unserviced = look.get_key(False) solutionDict[vehicleNumber] = {}.fromkeys(solutionKeys) solutionDict[vehicleNumber]['Load'] = Load solutionDict[vehicleNumber]['Cost'] = Cost totalCost = totalCost + Cost solutionDict[vehicleNumber]['Solution'] = Sequence nRoutes = len(solutionDict.keys()) solutionDict['Total cost'] = totalCost self.EPSsolution = solutionDict return (solutionDict, nRoutes)
def singleRouteIFulosoyHybridBalanced(self, rule, collectFlag): ''' Generate single route untill vehicle capacity is reached. Capacity is reached when the demand of the closest arcs exceeds the vehicles available capacity. Improvement would be to then look at second closest vertex. It is actual rather simple. Generate a list of arcs not yet seriviced whos demand can be met. And choose the closest of those edges. Might want to include a rule preventing edges to far away to be added. Radius or elpise rule? Improve perfomance by calculating remaining capacity and only looking at possible edges. ''' depot = self.info.depotArc vehicleCapacity = self.info.capacity vehicleMaxTrip = self.info.maxTrip dumpCost = self.info.dumpCost TripFull = False sequenceWithIFs = [] ifLoad = [] Cost = 0 nTrips = -1 while TripFull == False: Load = 0 Halfull = False VehicleFull = False collectedFind = dictFind.Lookup(collectFlag) Unserviced = collectedFind.get_key(False) Sequence = [] if Unserviced == []: break nTrips += 1 if nTrips == 0: Sequence = [depot] else: Sequence.append(sequenceWithIFs[nTrips - 1][-1]) while VehicleFull == False: collectedFind = dictFind.Lookup(collectFlag) Unserviced = collectedFind.get_key(False) if Unserviced == []: break nearest = [] NearestDist = 1e30000 LastEdge = Sequence[-1] for i in Unserviced: distanceNextEdge = self.info.spDistanceD[LastEdge][i] if distanceNextEdge < NearestDist: nearest = [] NearestDist = distanceNextEdge nearest.append(i) elif distanceNextEdge == NearestDist: nearest.append(i) if len(nearest) > 1: (VehicleFull, chooseNearest) = self.breakTie(rule, nearest, Halfull, Load) elif len(nearest) == 1: chooseNearest = nearest[0] else: break if (Load + self.info.demandD[chooseNearest]) > vehicleCapacity: VehicleFull = True if VehicleFull: bestOpt = 1e30000 for i in Unserviced: c = self.bestIFdistD[Sequence[-1]][i] if c < bestOpt: bestPlaced = i bestOpt = c bstIF = self.bestIF[Sequence[-1]][bestPlaced] Cost = Cost + self.info.spDistanceD[ Sequence[-1]][bstIF] + dumpCost Sequence.append(bstIF) break Cost = Cost + self.info.spDistanceD[LastEdge][ chooseNearest] + self.info.serveCostD[chooseNearest] dummyCost = Cost + dumpCost + self.bestIFdistD[chooseNearest][ depot] if dummyCost > vehicleMaxTrip: TripFull = True Cost = Cost - self.info.spDistanceD[LastEdge][ chooseNearest] - self.info.serveCostD[chooseNearest] break Load = Load + self.info.demandD[chooseNearest] if Load > vehicleCapacity / 2.0: Halfull = True Sequence.append(chooseNearest) collectFlag[chooseNearest] = True if self.info.invArcD[chooseNearest]: collectFlag[self.info.invArcD[chooseNearest]] = True sequenceWithIFs.append(Sequence[:]) ifLoad.append(copy.deepcopy(Load)) if Unserviced == []: break if TripFull: break if len(sequenceWithIFs[-1]) > 1: bstIF = self.bestIF[sequenceWithIFs[-1][-1]][depot] bstIFcost = self.bestIFdistD[sequenceWithIFs[-1][-1]][depot] Cost = Cost + bstIFcost + dumpCost sequenceWithIFs[-1].append(bstIF) sequenceWithIFs[-1].append(depot) else: del sequenceWithIFs[-1] Cost = Cost + self.info.spDistanceD[sequenceWithIFs[-1][-1]][depot] sequenceWithIFs[-1].append(depot) onlyArcs = [] i = 0 for seq in sequenceWithIFs: i += 1 if i == len(sequenceWithIFs): onlyArcs = onlyArcs + seq[1:-2] else: onlyArcs = onlyArcs + seq[1:-1] genUlusoyRoutes = UlusoyHeuristics.UlusoysIFs_1vehicle(self.info) (sequenceWithIFs, ifLoad, Cost) = genUlusoyRoutes.genSolutionList(onlyArcs) return (Cost, ifLoad, sequenceWithIFs, collectFlag)
def singleRoute(self, rule, collectFlag): ''' Generate single route untill vehicle capacity is reached. Capacity is reached when the demand of the closest arcs exceeds the vehicles available capacity. Improvement would be to then look at second closest vertex. It is actual rather simple. Generate a list of arcs not yet seriviced whos demand can be met. And choose the closest of those edges. Might want to include a rule preventing edges to far away to be added. Radius or elpise rule? Improve perfomance by calculating remaining capacity and only looking at possible edges. ''' depot = self.info.depotArc vehicleCapacity = self.info.capacity dumpCost = self.info.dumpCost Halfull = False VehicleFull = False Sequence = [depot] Cost = 0 Load = 0 while VehicleFull == False: collectedFind = dictFind.Lookup(collectFlag) Unserviced = collectedFind.get_key(False) if Unserviced == []: break nearest = [] NearestDist = 1e30000 LastEdge = Sequence[-1] for i in Unserviced: distanceNextEdge = self.info.spDistanceD[LastEdge][i] if distanceNextEdge < NearestDist: nearest = [] NearestDist = distanceNextEdge nearest.append(i) elif distanceNextEdge == NearestDist: nearest.append(i) if len(nearest) > 1: (VehicleFull, chooseNearest) = self.breakTie(rule, nearest, Halfull, Load) elif len(nearest) == 1: chooseNearest = nearest[0] else: break if VehicleFull: break elif (Load + self.info.demandD[chooseNearest]) > vehicleCapacity: break Cost = Cost + self.info.spDistanceD[LastEdge][ chooseNearest] + self.info.serveCostD[chooseNearest] Load = Load + self.info.demandD[chooseNearest] if Load > vehicleCapacity / 2.0: Halfull = True Sequence.append(chooseNearest) collectFlag[chooseNearest] = True if self.info.invArcD[chooseNearest]: collectFlag[self.info.invArcD[chooseNearest]] = True Cost = Cost + self.info.spDistanceD[Sequence[-1]][depot] + dumpCost Sequence.append(depot) return (Cost, Load, Sequence, collectFlag)