google-mapsoptimizationgoogle-route-optimization-api

How to group nearby stops to be visited sequentially using Google Route Optimization API?


I’m using the Google Route Optimization API to optimize 50 stops with one vehicle. I have around 10 points within a 100m radius, but after optimization, they are not visited sequentially (refer to the image).

Route Optimization Result

This is what my model looks like,

{
    "shipments": [
        {
            "pickups": [
                {
                    "arrival_location": {"latitude": 22.63253, "longitude": 88.21828},
                    "label": "A26731",
                    "tags": ["grp_tag"],
                }
            ]
        },
        # More stops here
    ],
    "vehicles": [
        {
            "label": "cluster2",
            "cost_per_kilometer": 10.0,
            "cost_per_hour": 10.0,
            "start_location": {"latitude": 22.62791, "longitude": 88.231},
        }
    ],
    "global_duration_cost_per_hour": 100,
    "global_start_time": datetime.datetime(2025, 1, 7, 7, 0),
    "global_end_time": datetime.datetime(2025, 1, 7, 23, 0),
    "transition_attributes": [
        {
            "excluded_dst_tag": "grp_tag",
            "excluded_src_tag": "grp_tag",
            "distance_limit": {
                "soft_max_meters": 200,
                "cost_per_kilometer_below_soft_max": 1,
                "cost_per_kilometer_above_soft_max": 5000,
            },
        }
    ],
}

I’ve tried using the transition attributes feature of Google RO but it doesn’t seem to work. What I want is the nearby stops to be visited sequentially, regardless of which side of the road the points are on.


Solution

  • You need to flip the transition_attributes costs; ideally setting the "above soft max" to 0 and "below soft max" to a non-negligible value (100 is plenty enough). That should cluster nearby visits together.

    "transition_attributes": [
            {
                "excluded_dst_tag": "%$@#",
                "excluded_src_tag": "%$@#",
                "distance_limit": {
                    "soft_max_meters": 200,
                    "cost_per_kilometer_below_soft_max": 100,
                },
            }
        ],