Ralf
Ralf

Reputation: 41

Google OR-Tools TSP returning several solution

I've been recently working on finding more than just the optimal route using Google's OR-Tools. I have found an example in the repo, but this only solves for the optimal route, any idea how to generate more than just one solution for a set of points? I'm currently working with the DotNet version of the tool, any solution with any other language would be helpful!

public class tspParams : NodeEvaluator2
{
    public static int[,] distanceMatrix =
    {
        {   0,  20,  40,   10   },
        {   20,  0,   4,   55   },
        {   40,  4,   0,   2    },
        {   10, 55,   2,   0    }
    };

    public static int tsp_size
    {
        get { return distanceMatrix.GetUpperBound(0) + 1; }
    }

    public static int num_routes
    {
        get { return 1; }
    }

    public static int depot
    {
        get { return 0; }
    }

    public override long Run(int FromNode, int ToNode)
    {
        return distanceMatrix[FromNode, ToNode];
    }
}

public class TSP
{
    public static void PrintSolution(RoutingModel routing, Assignment solution)
    {
        Console.WriteLine("Distance of the route: {0}", solution.ObjectiveValue());

        var index = routing.Start(0);

        Console.WriteLine("Route for Vehicle 0:");
        while (!routing.IsEnd(index))
        {
            Console.Write("{0} -> ", routing.IndexToNode(index));
            var previousIndex = index;
            index = solution.Value(routing.NextVar(index));
        }
        Console.WriteLine("{0}", routing.IndexToNode(index));
        //Console.WriteLine("Calculated optimal route!");
    }

    public static void Solve()
    {
        // Create Routing Model
        RoutingModel routing = new RoutingModel(
            tspParams.tsp_size, 
            tspParams.num_routes, 
            tspParams.depot);

        // Define weight of each edge
        NodeEvaluator2 distanceEvaluator = new tspParams();

        //protect callbacks from the GC
        GC.KeepAlive(distanceEvaluator);
        routing.SetArcCostEvaluatorOfAllVehicles(distanceEvaluator);

        // Setting first solution heuristic (cheapest addition).
        RoutingSearchParameters searchParameters = RoutingModel.DefaultSearchParameters();
        searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;

        Assignment solution = routing.SolveWithParameters(searchParameters);
        PrintSolution(routing, solution);
    }
}

Upvotes: 2

Views: 1859

Answers (1)

ihadanny
ihadanny

Reputation: 4483

Use AllSolutionCollector from the underlying CP solver. python code:

    solver = routing.solver()
    collector = solver.AllSolutionCollector()

    for location_idx in range(len(data['time_windows'])):
        index = manager.NodeToIndex(location_idx)
        time_var = time_dimension.CumulVar(index)
        next_var = routing.NextVar(index)
        collector.Add(time_var)
        collector.Add(next_var)
    for v in range(data['num_vehicles']):
        index = routing.Start(v)
        time_var = time_dimension.CumulVar(index)
        next_var = routing.NextVar(index)
        collector.Add(time_var)
        collector.Add(next_var)

        index = routing.End(v)
        time_var = time_dimension.CumulVar(index)
        collector.Add(time_var)

    routing.AddSearchMonitor(collector)

    assignment = routing.SolveFromAssignmentWithParameters(initial_solution, search_parameters)
    if assignment:
        logger.info("solution count: %d", collector.SolutionCount())
        for index in range(collector.SolutionCount()):
            logger.info("solution index: %d", index)
            self.print_solution(data, manager, routing, collector.Solution(index))
        logger.info('final solution:')
        self.print_solution(data, manager, routing, assignment)
    else:
        raise OptimizationInternalException("no solution found")

Upvotes: 3

Related Questions