Пример #1
0
    def calculeCost(self):
        cost = 0.0
        demand = 0.0
        duration = 0.0
        length = len(self._tour)

        #custo do depósito ao primeiro cliente
        customer = self._tour[0]
        cost += dist.euclidianDistance(customer.get_x_coord(),customer.get_y_coord(),self._depot.get_x_coord(),self._depot.get_y_coord())
        demand += customer.get_demand()
        duration += customer.get_duration()
        #custo do último cliente ao depósito
        customer = self._tour[length-1]
        cost += dist.euclidianDistance(customer.get_x_coord(),customer.get_y_coord(),self._depot.get_x_coord(),self._depot.get_y_coord())
        demand += customer.get_demand()
        duration += customer.get_duration()
        #custo dos clientes intermediários
        for i in range(length):

            if i+1 < length:
                customer = self._tour[i]
                nextCustomer = self._tour[i+1]
                cost += dist.euclidianDistance(customer.get_x_coord(),customer.get_y_coord(),nextCustomer.get_x_coord(),nextCustomer.get_y_coord())
            if i>0 and i<length-1:
                demand += customer.get_demand()
                duration += customer.get_duration()

        self._totalDemand = demand
        self._totalDuration = duration
        self._cost = cost
        self.updatePenalty()
Пример #2
0
    def costWithNode(self,customer,index):
        cost = 0.0
        load = self._totalDemand + customer.get_demand()
        duration = self._totalDuration + customer.get_duration()
        length = len(self._tour)

        if length == 0: #lista vazia:
            cost = 2 * dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),customer.get_x_coord(),customer.get_y_coord())
            load = customer.get_demand()
            duration = customer.get_duration()
        #verificar se ele ligará ao depósito
        elif index == 0:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[0].get_x_coord(),self._tour[0].get_y_coord()) + \
            dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),customer.get_x_coord(),customer.get_y_coord()) + \
            dist.euclidianDistance(customer.get_x_coord(),customer.get_y_coord(),self._tour[0].get_x_coord(),self._tour[0].get_y_coord())
        elif index == length:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[length-1].get_x_coord(),self._tour[length-1].get_y_coord()) + \
            dist.euclidianDistance(self._tour[length-1].get_x_coord(),self._tour[length-1].get_y_coord(),customer.get_x_coord(),customer.get_y_coord()) + \
            dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),customer.get_x_coord(),customer.get_y_coord())

        #está entre dois clientes
        else:
             cost = self._cost - dist.euclidianDistance(self._tour[index-1].get_x_coord(),self._tour[index-1].get_y_coord(),self._tour[index].get_x_coord(),self._tour[index].get_y_coord()) + \
             dist.euclidianDistance(self._tour[index-1].get_x_coord(),self._tour[index-1].get_y_coord(),customer.get_x_coord(),customer.get_y_coord()) + \
             dist.euclidianDistance(customer.get_x_coord(),customer.get_y_coord(),self._tour[index].get_x_coord(),self._tour[index].get_y_coord())

        #verificar se há penalizações
        costTotal = cost
        if load > self._depot.get_loadVehicle():
            costTotal += 1000 * (load - self._depot.get_loadVehicle())
        if duration > self._depot.get_durationRoute():
            costTotal += 1000 * (duration - self._depot.get_durationRoute())

        return [costTotal,cost,load,duration]
Пример #3
0
    def splitRoute(self, path, depot):
        n = len(path)
        # print("path")
        # print(path)
        # print(depot)
        vehicleCapacity = depot.get_loadVehicle()  # máximo carregamento
        durationRoute = depot.get_durationRoute()  # máxima duração
        v = []  # custo do menor caminho do depósito até o ponto.
        predecessor = []  # predecessores de cada idCsts neste caminho
        predecessor.append(-1)  # depósito não tem precedente
        v.append(0.0)
        # print("n = {}".format(len(path)))

        for i in range(n):
            v.append(SplitAlgorithms._infinite)
            # pior hipótese - número de rotas = número clientes
            predecessor.append(0)

        for i in range(1, n + 1):
            load = 0.0
            cost = 0.0
            j = i
            while (j <= n) and (load < vehicleCapacity) and (
                    cost < 2 * durationRoute):
                customer = path[j - 1]
                load += customer.get_demand()
                if i == j:
                    # custo de ida e volta
                    cost = 2 * dist.euclidianDistance(
                        customer.get_x_coord(), customer.get_y_coord(),
                        depot.get_x_coord(),
                        depot.get_y_coord()) + customer.get_service()
                else:
                    previewCustomer = path[j - 2]
                    cost = cost - dist.euclidianDistance(
                        previewCustomer.get_x_coord(),
                        previewCustomer.get_y_coord(), depot.get_x_coord(),
                        depot.get_y_coord()) + dist.euclidianDistance(
                            previewCustomer.get_x_coord(),
                            previewCustomer.get_y_coord(),
                            customer.get_x_coord(), customer.get_y_coord()
                        ) + customer.get_service() + dist.euclidianDistance(
                            customer.get_x_coord(), customer.get_y_coord(),
                            depot.get_x_coord(), depot.get_y_coord())

                if (load <= vehicleCapacity) and (cost <= 2 * durationRoute):
                    if (v[i - 1] + cost) < v[j]:
                        v[j] = v[i - 1] + cost
                        predecessor[j] = i - 1
                j += 1
                # print("cost: {} load: {}".format(cost, load))
                # print("pred: {}".format(predecessor))
                # print("v: {}".format(v))

        # print("\n")
        # print(predecessor)
        return predecessor
Пример #4
0
    def costWithoutNode(self, indexCst):
        cost = 0.0
        load = self._totalDemand - self._tour[indexCst].get_demand()
        service = self._totalService - self._tour[indexCst].get_service()
        length = len(self._tour)

        if length == 1:  #só tem esse cliente
            return [0, 0, 0, 0]
        #verificar se ele liga ao depósito
        elif indexCst == 0:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[indexCst].get_x_coord(),self._tour[indexCst].get_y_coord()) + \
            dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[1].get_x_coord(),self._tour[1].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexCst].get_x_coord(),self._tour[indexCst].get_y_coord(),self._tour[1].get_x_coord(),self._tour[1].get_y_coord())

        elif indexCst == length - 1:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[indexCst].get_x_coord(),self._tour[indexCst].get_y_coord()) + \
            dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[length-2].get_x_coord(),self._tour[length-2].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexCst].get_x_coord(),self._tour[indexCst].get_y_coord(),self._tour[length-2].get_x_coord(),self._tour[length-2].get_y_coord())
        #está entre dois clientes
        else:
            cost = self._cost - dist.euclidianDistance(self._tour[indexCst-1].get_x_coord(),self._tour[indexCst-1].get_y_coord(),self._tour[indexCst].get_x_coord(),self._tour[indexCst].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexCst].get_x_coord(),self._tour[indexCst].get_y_coord(),self._tour[indexCst+1].get_x_coord(),self._tour[indexCst+1].get_y_coord()) + \
            dist.euclidianDistance(self._tour[indexCst-1].get_x_coord(),self._tour[indexCst-1].get_y_coord(),self._tour[indexCst+1].get_x_coord(),self._tour[indexCst+1].get_y_coord())

        #verificar se há penalizações
        costTotal = cost
        if load > self._depot.get_loadVehicle():
            costTotal += 1000 * (load - self._depot.get_loadVehicle())
        if cost + service > self._depot.get_durationRoute():
            costTotal += 1000 * abs(service - self._depot.get_durationRoute())

        return [costTotal, cost, load, service]
Пример #5
0
    def propagatek(i, j, k, listCst, sumDistance, potential, depot):
        distDeptNextI = dist.euclidianDistance(
            listCst[i].get_x_coord(), listCst[i].get_y_coord(),
            depot.get_x_coord(),
            depot.get_y_coord())  # distancia de i+1 até o depósito
        distDeptJ = dist.euclidianDistance(
            listCst[j - 1].get_x_coord(), listCst[j - 1].get_y_coord(),
            depot.get_x_coord(),
            depot.get_y_coord())  # distancia de j até o depósito

        return potential[k][i] + sumDistance[j] - sumDistance[
            i + 1] + distDeptNextI + distDeptJ
Пример #6
0
    def dominatesRightk(i, j, k, listCst, sumDistance, potential, depot):
        distDeptNextJ = dist.euclidianDistance(listCst[j].get_x_coord(),
                                               listCst[j].get_y_coord(),
                                               depot.get_x_coord(),
                                               depot.get_y_coord())
        distDeptNextI = dist.euclidianDistance(listCst[i].get_x_coord(),
                                               listCst[i].get_y_coord(),
                                               depot.get_x_coord(),
                                               depot.get_y_coord())

        return (potential[k][j] + distDeptNextJ) < (
            potential[k][i] + distDeptNextI + sumDistance[j + 1] -
            sumDistance[i + 1] + 0.0001)
Пример #7
0
    def dominates(i, j, listCst, sumDistance, potential, sumLoad, depot):
        distDeptNextJ = dist.euclidianDistance(listCst[j].get_x_coord(),
                                               listCst[j].get_y_coord(),
                                               depot.get_x_coord(),
                                               depot.get_y_coord())
        distDeptNextI = dist.euclidianDistance(listCst[i].get_x_coord(),
                                               listCst[i].get_y_coord(),
                                               depot.get_x_coord(),
                                               depot.get_y_coord())

        return sumLoad[i] == sumLoad[j] and (potential[j] + distDeptNextJ) > (
            potential[i] + distDeptNextI + sumDistance[j + 1] -
            sumDistance[i + 1] - 0.0001)
Пример #8
0
    def splitRoute(path, depot):
        n = len(path)
        vehicleCapacity = depot.get_loadVehicle()
        durationRoute = depot.get_durationRoute()
        v = []  # custo do menor caminho do depósito até o ponto.
        predecessor = []  # predecessores de cada idCsts neste caminho
        predecessor.append(-1)  # depósito não tem precedente
        v.append(0.0)
        for i in range(n):
            v.append(SplitAlgorithms._infinite)
            predecessor.append("")

        for i in range(1, n + 1):
            load = 0.0
            cost = 0.0
            j = i
            duration = 0
            while (j <= n) and (load <= vehicleCapacity) and (duration <=
                                                              durationRoute):
                customer = path[j - 1]
                load += customer.get_demand()
                if i == j:
                    # custo de ida e volta
                    duration += customer.get_duration()
                    cost = 2 * dist.euclidianDistance(
                        customer.get_x_coord(), customer.get_y_coord(),
                        depot.get_x_coord(),
                        depot.get_y_coord()) + customer.get_duration()
                else:
                    duration += customer.get_duration()
                    previewCustomer = path[j - 2]
                    cost = cost - dist.euclidianDistance(
                        previewCustomer.get_x_coord(),
                        previewCustomer.get_y_coord(), depot.get_x_coord(),
                        depot.get_y_coord()) + dist.euclidianDistance(
                            previewCustomer.get_x_coord(),
                            previewCustomer.get_y_coord(),
                            customer.get_x_coord(), customer.get_y_coord()
                        ) + customer.get_duration() + dist.euclidianDistance(
                            customer.get_x_coord(), customer.get_y_coord(),
                            depot.get_x_coord(), depot.get_y_coord())

                if (load <= vehicleCapacity) and (duration <= durationRoute):
                    if (v[i - 1] + cost) < v[j]:
                        v[j] = v[i - 1] + cost
                        predecessor[j] = i - 1
                    j += 1
        return predecessor
Пример #9
0
    def calculeCost(self):
        cost = 0.0
        demand = 0.0
        service = 0.0
        length = len(self._tour)

        #custo do depósito ao primeiro cliente
        customer = self._tour[0]
        cost += dist.euclidianDistance(customer.get_x_coord(),
                                       customer.get_y_coord(),
                                       self._depot.get_x_coord(),
                                       self._depot.get_y_coord())

        #custo do último cliente ao depósito
        customer = self._tour[length - 1]
        cost += dist.euclidianDistance(customer.get_x_coord(),
                                       customer.get_y_coord(),
                                       self._depot.get_x_coord(),
                                       self._depot.get_y_coord())

        #custo dos clientes intermediários
        for i in range(length):
            customer = self._tour[i]
            demand += customer.get_demand()
            service += customer.get_service()
            if i + 1 < length:
                nextCustomer = self._tour[i + 1]
                cost += dist.euclidianDistance(customer.get_x_coord(),
                                               customer.get_y_coord(),
                                               nextCustomer.get_x_coord(),
                                               nextCustomer.get_y_coord())

        self._totalDemand = demand
        self._totalService = service
        self._cost = cost
        self.updatePenalty()
Пример #10
0
    def M10(self, solution):
        solution1 = copy.deepcopy(solution)
        depots = dpts.get_depotsList()
        #escolha da rota
        routes = solution1.get_routes()
        idRoute = np.random.randint(len(routes))
        route = copy.deepcopy(routes[idRoute])
        length = len(route.get_tour())  # comprimento da rota
        oldDepot = route.get_depot()
        costWithoutRoute = solution1.get_cost() - route.get_totalCost()
        penalty = route.get_totalCost() - route.get_costWithoutPenalty()
        extraPenalty = 0
        # print(penalty)
        cont = 0

        bestRoute = copy.deepcopy(route)
        # print("tamanho de rotas")
        # print(len(routes))
        # print("route")
        # print(route)
        if length > 0:
            route1 = copy.deepcopy(route)
            #rotação da rota
            for i in range(length):
                #rotacionar
                # print(route1)
                aux = route1.get_tour()[0]
                # print(aux)
                cost = route1.costWithoutNode(0)
                route1.removeCustomer(aux)
                route1.set_cost(cost[1], cost[2], cost[3])
                cost = route1.costWithNode(aux, length - 1)
                route1.addCustomer(aux)
                route1.set_cost(cost[1], cost[2], cost[3])
                # print(route1)
                # print("-----")
                # verificar se rota gerada é melhor (considerando mesmo depósito)
                if bestRoute.get_totalCost() > route1.get_totalCost():
                    extraPenalty = 0
                    bestRoute = copy.deepcopy(route1)
                    cont = 1
                # verificar transferência da rota em outro depósito
                for dpt in depots.values():
                    if str(dpt) != str(oldDepot):
                        # verificar rota para o novo depósito
                        tour = route1.get_tour()
                        # tirar o custo associado ao depósito
                        cost1 = route1.get_totalCost() - dist.euclidianDistance(tour[0].get_x_coord(),
                                tour[0].get_y_coord(), oldDepot.get_x_coord(), oldDepot.get_y_coord()) - \
                                dist.euclidianDistance(tour[length-1].get_x_coord(),
                                tour[length-1].get_y_coord(), oldDepot.get_x_coord(), oldDepot.get_y_coord())

                        # computar custo com o novo depósito
                        newCost = cost1 + dist.euclidianDistance(tour[0].get_x_coord(),
                            tour[0].get_y_coord(), dpt.get_x_coord(), dpt.get_y_coord()) + \
                            dist.euclidianDistance(tour[length-1].get_x_coord(),
                            tour[length-1].get_y_coord(), dpt.get_x_coord(), dpt.get_y_coord())

                        if bestRoute.get_totalCost() > newCost:
                            # verifica número de veículos utilizados pelo depósito
                            nVehicles = 0
                            for r in solution1.get_routes():
                                if r.get_depot() == dpt:
                                    nVehicles += 1
                            if nVehicles < dpt.get_numberVehicles():
                                if (costWithoutRoute + newCost
                                    ) < solution1.get_cost():  # é melhor
                                    extraPenalty = 0
                                    bestRoute = copy.deepcopy(route1)
                                    bestRoute.set_depot(dpt)
                                    newCost1 = newCost - penalty
                                    bestRoute.set_cost(
                                        newCost1, bestRoute.get_totalDemand(),
                                        bestRoute.get_totalService())

                                    cont = 1
                            # else:
                            #     if (costWithoutRoute + newCost + 1000) < solution1.get_cost(): # ainda é melhor
                            #         extraPenalty = 1000 #penalização por rota a mais
                            #         bestRoute.set_depot(dpt)
                            #         newCost1 = newCost - penalty
                            #         bestRoute.set_cost(newCost1, bestRoute.get_totalDemand(),
                            #             bestRoute.get_totalService())
                            #         cont = 1

            if cont == 1:
                # print(penalty)
                # # print(bestRoute.get_totalCost())
                # print(route)
                # # print("best")
                # print(bestRoute)
                solution1.setRoute(bestRoute, idRoute)
                solution1.formGiantTour()
                solution1.calculateCost(extraPenalty)
                return solution1

        return solution
Пример #11
0
    def splitLinearBounded(solution):
        solution1 = copy.deepcopy(solution)
        solution2 = copy.deepcopy(solution)
        depotsList = dpts.get_depotsList()
        customers = solution1.get_giantTour()
        depots = solution1.get_depots()
        for dpt in depotsList:
            listCst = []
            depot = depotsList[dpt]
            for j in range(len(customers)):
                if dpt == str(depots[j].get_id()):
                    listCst.append(customers[j])

            sumDistance = [0.0 for x in range(len(listCst) + 1)]
            sumLoad = [0.0 for x in range(len(listCst) + 1)]
            sumDistance[0] = 0  # distancia do depósito
            # distância do depósito ao primeiro nó
            sumDistance[1] = dist.euclidianDistance(listCst[0].get_x_coord(),
                                                    listCst[0].get_y_coord(),
                                                    depot.get_x_coord(),
                                                    depot.get_y_coord())

            sumLoad[0] = 0
            sumLoad[1] = customers[0].get_demand()
            # inicializar com o somatório distancia de i-1 a i e a demanda de i-1 a i
            for i in range(2, len(listCst) + 1):
                sumDistance[i] = sumDistance[i - 1] + dist.euclidianDistance(
                    listCst[i - 2].get_x_coord(), listCst[i - 2].get_y_coord(),
                    listCst[i - 1].get_x_coord(), listCst[i - 1].get_y_coord())
                sumLoad[i] = sumLoad[i - 1] + listCst[i - 1].get_demand()

            potential = []
            pred = []

            for k in range(depot.get_numberVehicles() + 1):
                potential.append([1.e30 for x in range(len(listCst) + 1)])
                pred.append([-1 for x in range(len(listCst) + 1)])

            potential[0][0] = 0

            for k in range(depot.get_numberVehicles()):
                queue = [k]
                i = k + 1
                while (i <= len(listCst)) and (len(queue) > 0):
                    # o primeiro da fila será o melhor predecessor de i
                    potential[k + 1][i] = SplitAlgorithms.propagatek(
                        queue[0], i, k, listCst, sumDistance, potential,
                        depot)  # calcula custo de i a j
                    pred[k + 1][i] = queue[0]

                    # se i não é dominado pelo último da pilha
                    if i < len(listCst):
                        if not (SplitAlgorithms.dominatesk(
                                queue[len(queue) - 1], i, k, listCst,
                                sumDistance, potential, sumLoad, depot)):
                            # então i será inserido, precisando remover quem ele domina
                            while len(
                                    queue
                            ) > 0 and SplitAlgorithms.dominatesRightk(
                                    queue[len(queue) - 1], i, k, listCst,
                                    sumDistance, potential, depot):
                                del queue[len(queue) - 1]
                            queue.append(i)

                        # Verifica se a frente consegue chegar ao próximo nó, caso contrário ele desaparecerá.
                        while len(queue) > 0 and (
                                sumLoad[i + 1] - sumLoad[queue[0]]) > (
                                    depot.get_loadVehicle() + 0.0001):
                            del queue[0]

                    i += 1

            if potential[depot.get_numberVehicles()][len(listCst)] > 1.e29:
                # print("ERRO: nenhuma solução de divisão foi propagada até o último nó")
                del solution1
                return SplitAlgorithms.mountRoutes(solution2)

            else:
                # achando o número ótimo de rotas
                minCost = 1.e30
                nRoutes = 0
                for k in range(1, depot.get_numberVehicles() + 1):
                    if potential[k][len(listCst)] < minCost:
                        minCost = potential[k][len(listCst)]
                        # print("minCost "+str(minCost))
                        nRoutes = k

                cour = len(listCst)
                for i in range(nRoutes - 1, -1, -1):
                    route = Route(depot)
                    j = pred[i + 1][cour]
                    for k in range(j + 1, cour + 1):
                        route.addCustomer(listCst[k - 1])
                    cour = j
                    # calcular custo da rota formada
                    route.startValues()
                    route.calculeCost()
                    solution1.addRoutes(route)

        solution1.formGiantTour()
        solution1.calculateCost()
        # print(solution)
        return solution1
Пример #12
0
    def splitLinear(solution, limitRoutes=True):
        solution1 = copy.deepcopy(solution)
        depotsList = dpts.get_depotsList()
        customers = solution1.get_giantTour()
        depots = solution1.get_depots()
        penalty = 0.0
        for dpt in depotsList:
            listCst = []
            depot = depotsList[dpt]
            for j in range(len(customers)):
                if dpt == str(depots[j].get_id()):
                    listCst.append(customers[j])

            lenListCst = len(listCst)
            sumDistance = []
            sumLoad = []
            potential = []
            pred = []

            for x in range(lenListCst + 1):
                sumDistance.append(0.0)
                sumLoad.append(0.0)
                potential.append(1.e30)
                pred.append(-1)

            sumDistance[0] = 0  # distancia do depósito
            # distância do depósito ao primeiro nó
            sumDistance[1] = dist.euclidianDistance(listCst[0].get_x_coord(),
                                                    listCst[0].get_y_coord(),
                                                    depot.get_x_coord(),
                                                    depot.get_y_coord())

            sumLoad[0] = 0
            sumLoad[1] = customers[0].get_demand()
            potential[0] = 0

            # inicializar com o somatório distancia de i-1 a i e a demanda de i-1 a i
            for i in range(2, lenListCst + 1):
                sumDistance[i] = sumDistance[i - 1] + dist.euclidianDistance(
                    listCst[i - 2].get_x_coord(), listCst[i - 2].get_y_coord(),
                    listCst[i - 1].get_x_coord(), listCst[i - 1].get_y_coord())
                sumLoad[i] = sumLoad[i - 1] + listCst[i - 1].get_demand()

            queue = [0]

            for i in range(1, lenListCst + 1):
                # da frente é o melhor predecessor de 1
                potential[i] = SplitAlgorithms.propagate(
                    queue[0], i, listCst, sumDistance, potential, depot)
                pred[i] = queue[0]

                if i < lenListCst:
                    # se i não é dominado pelo último da pilha
                    if not SplitAlgorithms.dominates(
                            queue[len(queue) - 1], i, listCst, sumDistance,
                            potential, sumLoad, depot):
                        # então i será inserido, precisando remover quem ele domina
                        while len(
                                queue) > 0 and SplitAlgorithms.dominatesRight(
                                    queue[len(queue) - 1], i, listCst,
                                    sumDistance, potential, depot):
                            del queue[len(queue) - 1]
                        queue.append(i)
                    # Verifica se a frente consegue chegar ao próximo nó, caso contrário ele desaparecerá.
                    while len(queue) > 0 and (sumLoad[i + 1] - sumLoad[
                            queue[0]]) > (depot.get_loadVehicle() + 0.0001):
                        del queue[0]

            if potential[len(listCst)] > 1.e29:
                print(
                    "ERRO: nenhuma solução de divisão foi propagada até o último nó"
                )
                exit(1)
            else:
                # achando o número ótimo de rotas
                minCost = 1.e30
                nRoutes = 0
                cour = lenListCst
                while cour > 0:
                    cour = pred[cour]
                    nRoutes += 1

                cour = len(listCst)
                # print(listCst)
                # print(pred)
                # print(cour)
                trip = []
                for i in range(nRoutes - 1, -1, -1):
                    t = []

                    j = pred[cour]
                    load = 0
                    for k in range(j + 1, cour + 1):
                        t.append(listCst[k - 1])
                        load += listCst[k - 1].get_demand()
                    cour = j
                    trip.append([t, load])

                # se o número de rotas formadas for maior que o número de veículos, juntar as de menor demanda
                numberVehicles = depot.get_numberVehicles()
                if nRoutes > numberVehicles:
                    # ordenada em ordem crescente de demanda
                    trip = sorted(trip, key=lambda x: x[1])
                    # juntar rotas com menor demanda
                    aux = len(trip) - numberVehicles
                    aux1 = aux

                    if limitRoutes:
                        while aux > 0:
                            r0 = trip[0][0]
                            r1 = trip[1][0]
                            r0 = r0 + r1
                            demand = trip[0][1] + trip[1][1]
                            trip[0] = [r0, demand]
                            del trip[1]
                            # ordenada em ordem crescente de demanda
                            trip = sorted(trip, key=lambda x: x[1])
                            aux -= 1
                    else:
                        penalty += 1000 * aux1

                # adicionar rotas a solucao
                for r in trip:
                    route = Route(depot)
                    # print("r")
                    # print(r)
                    for c in r[0]:
                        # print("c")
                        # print(c)
                        route.addCustomer(c)
                    # calcular custo da rota formada
                    route.startValues()
                    route.calculeCost()
                    solution1.addRoutes(route)

        solution1.formGiantTour()
        solution1.calculateCost(penalty)
        # print(solution1.get_routes())
        # exit(1)
        return solution1
Пример #13
0
    def randomDistribution():
        #print('Entrou aqui')
        #np.random.seed(idum)
        SplitDepots._individual = Solution()
        customersList = copy.deepcopy(csts.get_customersList())  # dicionário
        # lista com as chaves dos clientes
        keysCst = list(customersList.keys())
        depots = dpts.get_depotsList()  # dicionário
        nDepots = len(depots)
        base = len(customersList) / float(nDepots)
        maxCustomers = round(config.FRAC_MAX_DISTRIBUTION * base)

        nCustomers = len(keysCst)
        solution = {}

        # (depósito, [total de demanda, número de clientes alocados]
        control = {}

        for depot in depots:
            control[depot] = [0, 0]
        while nCustomers > 0:  # enquanto tiver cliente não alocado
            # cliente aleatório
            idCst = np.random.randint(0, len(keysCst))
            customer = customersList[keysCst[idCst]]
            # depósito mais próximo
            i = 0
            dpt = customer.get_depotsDistances()[i]
            cont = len(customer.get_depotsDistances())
            aux = 0
            while (control[str(dpt[0])][0] >=
                   depots[str(dpt[0])].get_loadTotal() + 0.0001 or
                   (cont > 1
                    and control[str(dpt[0])][1] > maxCustomers)) and cont > 0:
                if cont == 1:
                    aux = 1  # indica que todos os depósitos anteriores estão lotados
                i += 1
                dpt = customer.get_depotsDistances()[i]
                cont -= 1

            depot = depots[str(dpt[0])]
            control[str(
                dpt[0])][0] = control[str(dpt[0])][0] + customer.get_demand()
            control[str(dpt[0])][1] = control[str(dpt[0])][1] + 1

            # adicionar cliente ao depósito
            SplitDepots._individual.addGiantTour(customer, depot)
            del keysCst[idCst]  # atualizar lista
            nCustomers -= 1
            # escolher três clientes aleatórios
            if len(keysCst) > 0:
                idcst1 = np.random.randint(0, len(keysCst))
                neighbor1 = customersList[keysCst[idcst1]]
                dist1 = dist.euclidianDistance(customer.get_x_coord(),
                                               customer.get_y_coord(),
                                               neighbor1.get_x_coord(),
                                               neighbor1.get_y_coord())
                idcst2 = np.random.randint(0, len(keysCst))
                neighbor2 = customersList[keysCst[idcst2]]
                dist2 = dist.euclidianDistance(customer.get_x_coord(),
                                               customer.get_y_coord(),
                                               neighbor2.get_x_coord(),
                                               neighbor2.get_y_coord())
                idcst3 = np.random.randint(0, len(keysCst))
                neighbor3 = customersList[keysCst[idcst3]]
                dist3 = dist1 = dist.euclidianDistance(customer.get_x_coord(),
                                                       customer.get_y_coord(),
                                                       neighbor3.get_x_coord(),
                                                       neighbor3.get_y_coord())
                # ver o mais próximo ao cliente
                if dist1 <= dist2 and dist1 <= dist3:
                    close = neighbor1
                    id = idcst1
                elif dist2 <= dist1 and dist2 <= dist3:
                    close = neighbor2
                    id = idcst2
                else:
                    close = neighbor3
                    id = idcst3

                control[str(
                    dpt[0])][0] = control[str(dpt[0])][0] + close.get_demand()
                control[str(dpt[0])][1] = control[str(dpt[0])][1] + 1

                if (control[str(dpt[0])][0] <= depot.get_loadTotal() + 0.0001
                        and
                        control[str(dpt[0])][1] <= maxCustomers) or aux == 1:
                    # adicionar vizinho mais próximo a solução
                    SplitDepots._individual.addGiantTour(close, depot)
                    del keysCst[id]  # atualizar lista
                    nCustomers -= 1
                else:
                    control[str(dpt[0])][0] = control[str(
                        dpt[0])][0] - close.get_demand()
                    control[str(dpt[0])][1] = control[str(dpt[0])][1] - 1

        # print(self._individual.get_giantTour())
        # print(SplitDepots._individual.get_depots())
        return SplitDepots._individual
Пример #14
0
    def costWith2Nodes(self, customer1, customer2, index):
        cost = 0.0
        load = self._totalDemand + customer1.get_demand(
        ) + customer2.get_demand()
        service = self._totalService + customer1.get_service(
        ) + customer2.get_service()
        length = len(self._tour)

        #verificar se ele ligará ao depósito
        if length == 0:  #lista vazia:
            cost = dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),customer1.get_x_coord(),customer1.get_y_coord()) + \
            dist.euclidianDistance(customer1.get_x_coord(),customer1.get_y_coord(),customer2.get_x_coord(),customer2.get_y_coord()) + \
            dist.euclidianDistance(customer2.get_x_coord(),customer2.get_y_coord(),self._depot.get_x_coord(),self._depot.get_y_coord())
            load = customer1.get_demand() + customer2.get_demand()
            service = customer1.get_service() + customer2.get_service()
        elif index == 0:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[0].get_x_coord(),self._tour[0].get_y_coord()) + \
            dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),customer1.get_x_coord(),customer1.get_y_coord()) + \
            dist.euclidianDistance(customer1.get_x_coord(),customer1.get_y_coord(),customer2.get_x_coord(),customer2.get_y_coord()) + \
            dist.euclidianDistance(customer2.get_x_coord(),customer2.get_y_coord(),self._tour[0].get_x_coord(),self._tour[0].get_y_coord())
        elif index == length:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[length-1].get_x_coord(),self._tour[length-1].get_y_coord()) + \
            dist.euclidianDistance(self._tour[length-1].get_x_coord(),self._tour[length-1].get_y_coord(),customer1.get_x_coord(),customer1.get_y_coord()) + \
            dist.euclidianDistance(customer1.get_x_coord(),customer1.get_y_coord(),customer2.get_x_coord(),customer2.get_y_coord()) + \
            dist.euclidianDistance(customer2.get_x_coord(),customer2.get_y_coord(),self._depot.get_x_coord(),self._depot.get_y_coord())
        #está entre dois clientes
        else:
            cost = self._cost - dist.euclidianDistance(self._tour[index-1].get_x_coord(),self._tour[index-1].get_y_coord(),self._tour[index].get_x_coord(),self._tour[index].get_y_coord()) + \
            dist.euclidianDistance(self._tour[index-1].get_x_coord(),self._tour[index-1].get_y_coord(),customer1.get_x_coord(),customer1.get_y_coord()) + \
            dist.euclidianDistance(customer1.get_x_coord(),customer1.get_y_coord(),customer2.get_x_coord(),customer2.get_y_coord()) + \
            dist.euclidianDistance(customer2.get_x_coord(),customer2.get_y_coord(),self._tour[index].get_x_coord(),self._tour[index].get_y_coord())

        #verificar se há penalizações
        costTotal = cost
        if load > self._depot.get_loadVehicle():
            costTotal += 1000 * (load - self._depot.get_loadVehicle())
        if cost + service > self._depot.get_durationRoute():
            costTotal += 1000 * abs(service - self._depot.get_durationRoute())

        return [costTotal, cost, load, service]
Пример #15
0
    def costWithout2Nodes(self,indexFst):
        cost = 0.0
        load = self._totalDemand - self._tour[indexFst].get_demand() - self._tour[indexFst+1].get_demand()
        duration = self._totalDuration - self._tour[indexFst].get_duration() - self._tour[indexFst+1].get_duration()
        length = len(self._tour)

        if length == 2:#só tem esses 2 clientes
            return [0,0,0,0]
        #verificar se o primeiro liga ao depósito
        elif indexFst == 0:
            cost = self._cost - dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[0].get_x_coord(),self._tour[0].get_y_coord()) - \
            dist.euclidianDistance(self._tour[0].get_x_coord(),self._tour[0].get_y_coord(),self._tour[1].get_x_coord(),self._tour[1].get_y_coord()) - \
            dist.euclidianDistance(self._tour[1].get_x_coord(),self._tour[1].get_y_coord(),self._tour[2].get_x_coord(),self._tour[2].get_y_coord()) + \
            dist.euclidianDistance(self._depot.get_x_coord(),self._depot.get_y_coord(),self._tour[2].get_x_coord(),self._tour[2].get_y_coord())

        elif indexFst == length-2:
            cost = self._cost - dist.euclidianDistance(self._tour[length-3].get_x_coord(),self._tour[length-3].get_y_coord(),self._tour[indexFst].get_x_coord(),self._tour[indexFst].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexFst].get_x_coord(),self._tour[indexFst].get_y_coord(),self._tour[indexFst+1].get_x_coord(),self._tour[indexFst+1].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexFst+1].get_x_coord(),self._tour[indexFst+1].get_y_coord(),self._depot.get_x_coord(),self._depot.get_y_coord()) + \
            dist.euclidianDistance(self._tour[length-3].get_x_coord(),self._tour[length-3].get_y_coord(),self._depot.get_x_coord(),self._depot.get_y_coord())
        #está entre dois clientes
        else:

            cost = self._cost - dist.euclidianDistance(self._tour[indexFst-1].get_x_coord(),self._tour[indexFst-1].get_y_coord(),self._tour[indexFst].get_x_coord(),self._tour[indexFst].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexFst].get_x_coord(),self._tour[indexFst].get_y_coord(),self._tour[indexFst+1].get_x_coord(),self._tour[indexFst+1].get_y_coord()) - \
            dist.euclidianDistance(self._tour[indexFst+1].get_x_coord(),self._tour[indexFst+1].get_y_coord(),self._tour[indexFst+2].get_x_coord(),self._tour[indexFst+2].get_y_coord()) + \
            dist.euclidianDistance(self._tour[indexFst-1].get_x_coord(),self._tour[indexFst-1].get_y_coord(),self._tour[indexFst+2].get_x_coord(),self._tour[indexFst+2].get_y_coord())
        #verificar se há penalizações
        costTotal = cost
        if load > self._depot.get_loadVehicle():
            costTotal += 1000 * (load - self._depot.get_loadVehicle())
        if duration > self._depot.get_durationRoute():
            costTotal += 1000 * (duration - self._depot.get_durationRoute())

        return [costTotal,cost,load,duration]