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)