def apply(self, manager:  pywrapcp.RoutingModel, routing: pywrapcp.RoutingModel, data_model: DataModel):
        def distance_callback(from_index, to_index):
            """Returns the distance between the two nodes."""
            # Convert from routing variable Index to distance matrix NodeIndex.
            from_node = manager.IndexToNode(from_index)
            to_node = manager.IndexToNode(to_index)
            return data_model.distance_matrix[from_node][to_node]

        transit_callback_index = routing.RegisterTransitCallback(distance_callback)
        routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

        dimension_name = 'Distance'
        routing.AddDimension(
            transit_callback_index,
            0,  # no slack
            3000,  # vehicle maximum travel distance
            True,  # start cumul to zero
            dimension_name)
        distance_dimension = routing.GetDimensionOrDie(dimension_name)
        distance_dimension.SetGlobalSpanCostCoefficient(100)

        for i in range(data_model.number_of_engineers):
            routing.AddVariableMinimizedByFinalizer(
                distance_dimension.CumulVar(routing.Start(i)))
            routing.AddVariableMinimizedByFinalizer(
                distance_dimension.CumulVar(routing.End(i)))

        return routing
Ejemplo n.º 2
0
    def _set_balance_constraints_on_distance_driven(
            self, data: VehicleRoutingProblemInstance, routing: RoutingModel,
            deliveries: List[Delivery]):
        # ========= BALANCE DISTRIBUTION CONSTRAIN =========
        # https://activimetrics.com/blog/ortools/counting_dimension/
        # A “fair” distribution of loads
        average_load = int(
            2 * len(deliveries) //
            data.num_plans_to_create)  # each delivery has 2 locations
        count_dimension = routing.GetDimensionOrDie(
            self.DISTANCE_DIMENSION_NAME)
        for veh in range(0, data.num_plans_to_create):
            index_end = routing.End(veh)

            # https://github.com/google/or-tools/blob/v8.0/ortools/constraint_solver/routing.h#L2460
            # 5 min penalty for every order over average load
            count_dimension.SetCumulVarSoftLowerBound(index_end, average_load,
                                                      5 * 60)
Ejemplo n.º 3
0
    def _set_balance_constraints_on_number_of_packages(
            self, data: VehicleRoutingProblemInstance, routing: RoutingModel):
        # ========= BALANCE DISTRIBUTION CONSTRAIN =========
        routing.AddConstantDimension(
            1,  # increment by one every time
            100000,  # max value forces equivalent # of jobs
            True,  # set count to zero
            self.COUNT_DIMENSION_NAME)

        average_load = int(
            2 * len(data.drop_nodes) //
            data.num_plans_to_create)  # each delivery has 2 locations
        count_dimension = routing.GetDimensionOrDie(self.COUNT_DIMENSION_NAME)
        for veh in range(0, data.num_plans_to_create):
            index_end = routing.End(veh)

            # https://github.com/google/or-tools/blob/v8.0/ortools/constraint_solver/routing.h#L2460
            # 5 min penalty for every order over average load
            count_dimension.SetCumulVarSoftUpperBound(index_end,
                                                      average_load + 6, 5 * 60)
Ejemplo n.º 4
0
    def _set_time_dimension_constraints(
            self, routing: RoutingModel, manager: RoutingIndexManager,
            dimension_name: str,
            start_time_windows: List[TimeWindowConstraint],
            node_time_windows: List[TimeWindowConstraint],
            num_plans_to_create: int):

        # ========= TIME WINDOW =========
        time_dimension = routing.GetDimensionOrDie(dimension_name)
        for constraint in start_time_windows:
            index = routing.Start(constraint.node)
            self._set_constraint_on_var(index, constraint, time_dimension)

        for constraint in node_time_windows:
            index = manager.NodeToIndex(constraint.node)
            self._set_constraint_on_var(index, constraint, time_dimension)

        # Instantiate route start and end times to produce feasible times.
        for i in range(num_plans_to_create):
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.Start(i)))
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.End(i)))