Use cases

This section contains examples of settings for different scenarios of using Calendar Planning.

Planning by location and visit

You can plan routes in multiple ways:

  1. If all location visits have the same type, specify a list of locations on the locations sheet, setting the following parameters for each location:

    In this case, you don't need the visits sheet in the planning file.

  2. If locations have different types of visits that must be completed in a specific sequence, they must be configured on the visits sheet. The handling time, penalty for not visiting a location, and days of visits are specified for all visit types on the visits sheet, while time windows as well as the number and frequency of visits are specified for an individual location as a whole on the locations sheet.

  3. You can combine methods 1 and 2: specify visit types only for some locations and specify only location parameters for the rest of them.

Example 1

2 employees visit 20 locations. The handling time (service_duration_s), days of visits (allowed_days, preferred_days, mandatory_days, and denied_days), penalties for skipping a visit (penalty.visit_count.per_visit) and for skipping all visits (penalty.drop) are set for them on the locations sheet.

API request (JSON)API response

Example 2

The same as in example 1, but visit types are set for all locations on the visits sheet. The handling time (service_duration_s), days of visits (allowed_days, preferred_days, and denied_days), and a penalty for skipping a visit (drop) are set for each visit type.

API request (JSON)API response

Example 3

The same as in example 1, but locations 1 and 3 have set visit types on the visits sheet. For all other locations, visit types aren't set, and their parameters are specified only on the locations sheet.

API request (JSON)API response

Location and visit priorities

You can prioritize visits to locations using the following methods:

For each of these methods, you can additionally use the late_days_cost_increment parameter to plan visits to priority locations on the earliest days.

Setting priorities

You can set priorities for visiting all or some locations directly using the priority parameter on the locations sheet. For more information, see Priorities.

Example

The planning involves 2 employees who need to visit 32 locations that have been assigned different priorities: 0, 1, or without priority.

As a result of planning, employees visit all locations with priority 0 or without priority. Locations with priority 1 remain unassigned.

API request (JSON)API response

Prioritization using penalties

To prioritize locations and visits, you can impose penalties for not visiting locations and for skipping particular visit types. The higher the penalty, the more likely the location or visit being planned.

You can use the following parameters:

  • For locations — on the locations sheet:

    • penalty.drop: Fixed penalty if no visits to the location have been planned.
    • penalty.visit_count.fixed: Fixed penalty if at least one visit to the location has been skipped.
    • penalty.visit_count.per_visit: Penalty for each skipped visit to the location.
  • For specific visit types — on the visits sheet, specify the drop parameter value (locations.visits.N.drop in the API request). It will replace the penalty.visit_count.per_visit value for visits of this type.

For more information about the parameters used for planning visits, see Number and frequency of visits to locations and Visit types.

Example 1

The planning involves 2 employees who need to visit 32 locations with the same priority. Each location has a hard time window, so no delays or early arrivals are allowed. The penalty for not visiting a location is penalty.drop = 0.

As a result of planning, employees never visit location 3 and skip several visits to locations 1 and 7.

API request (JSON)API response

Example 2

The same as in example 1, but location 3 has a high priority, so its penalty.drop = 1,000,000.

As a result of planning, employees visit location 3, and visits to locations 25 and 29 remain unassigned.

API request (JSON)API response

Example 3

The same as in example 1, but the visits sheet contains drop penalties for skipping different types of visits to location 1 in descending order of the visit type priority:

  • 1,000,000: Inventory.
  • 500,000: Ad installation.
  • 100,000: Stocking.

As a result, all locations and visits are planned except for two stocking visits at location 1.

API request (JSON)API response

Prioritization using tags

You can prioritize visits to a location using optional tags. To do this, open the locations sheet, then enter the tag name in the optional_tags.0.tag field and its weight (more than 0) in the optional_tags.0.value field. The greater the tag weight, the more likely a visit to these locations will be planned.

Example

2 employees need to visit 49 locations. 8 locations are marked with the optional VIP tag with a weight of 3000.

As a result of planning, all VIP locations are distributed among employees, and some untagged locations remain unassigned.

API request (JSON)API response

Visits on the earliest days

To visit priority locations on earlier days, you can set the late_days_cost_increment parameter on the options sheet. To learn how this parameter works, see Visits on the earliest days.

Example 1

An employee needs to visit 40 locations, the late_days_cost_increment parameter isn't used. As a result, visits to locations are planned for 5 days.

API request (JSON)API response

Example 2

The same as in example 1, but the parameter late_days_cost_increment on the options sheet is set to 1000. As a result, visits to locations are planned for 4 days.

API request (JSON)API response

Visiting remote locations

One or multiple locations may be located far away from the others. In this case, the cost of visiting such a location may be higher than the penalty for not visiting it or skipping one of the visits, and the location will be unassigned. To avoid this, you can set higher penalties for remote locations on the locations sheet:

  • penalty.visit_count.per_visit: For skipping one visit to the location.
  • penalty.drop: For skipping all visits.

The cost of visiting a location can consist of the employee's hourly rate, kilometers in the route, start of the shift (if an additional employee has to be sent to the remote location), and other parameters. For more information, see Cost of work and payouts to employees.

Example 1

2 employees visit 18 locations. One of them (Location 2) is a remote one. The penalty for not visiting a location drop is 1000 for all locations, and the penalty for skipping a visit penalty.visit_count.per_visit is 17. By default, the cost of an employee starting their shift cost.fixed is 3000 — this is more than the total penalty for not visiting a location. As a result, the remote location remains unassigned.

API request (JSON)API response

Example 2

The same as in example 1, but the penalty for skipping a visit penalty.visit_count.per_visit to the remote location has been increased to 3500 — this is more than the cost of starting a route. As a result, on certain days, the second employee starts their shift specifically to visit the remote location.

API request (JSON)API response

Planning based on employees' skills

Sometimes, locations need to be visited by an employee with special skills or equipment. To plan routes taking into account these requirements, use location and employee tags.

In the required_tags field on the locations sheet, list comma-separated tags that determine the mandatory requirements for visiting a location. Optional requirements are specified in the optional_tags.N.tag and optional_tags.N.value fields. For more information, see Location tags.

If the employee meets the location requirements, list the appropriate tags in the tags field on the employees sheet. If the employee mustn't visit locations with specific tags, specify them in the excluded_tags field. For more information, see Employee tags.

Example

An employee must wear a uniform or have a thermal bag to visit some locations. Such locations have the uniform and fridge tags in the required_tags field. Locations 7 and 12 should be visited by employees with a pharmacology degree, so these locations have the optional pharmacy tag. Employee 1 has no relevant education, so the pharmacy tag is specified in the excluded_tags field for them.

As a result of planning, locations with special requirements are distributed among employees with the corresponding tags. Employee 1 visits locations that don't have the optional pharmacy tag.

API request (JSON)API response

Dense routes

To help employees spend less time traveling between locations, plan routes where locations are as close to each other as possible. There are two ways to do this:

  • Using the global_proximity_factor and daily_proximity_factor density parameters.
  • Using restrictions on route segments and factors for starting and end segments.

Density parameters

For employees to visit nearby locations sequentially, use the following parameters:

  • global_proximity_factor: Density parameter for the entire planning period.
  • daily_proximity_factor: Density parameter for a day.

You can set these parameters globally for all employees on the options sheet or individually for specific employees on the employees sheet.

Density parameters can take a value between 0 and 10, where 0 means no density, and 10 means maximum density. The recommended value range is from 0 to 1 (0 by default).

For more information, see Route density.

Example

Locations are primarily in the center, north, and south of the city. For routes to be more dense, global_proximity_factor was set to 0.2 and daily_proximity_factor was set to 0.5.

This resulted in the employees' routes becoming more geographically grouped.

API request (JSON)API response

Route segment restrictions

You can set restrictions on the distance between neighboring locations or the travel time between them on the employees sheet using the max_edge_distance_m and max_edge_duration_s parameters, respectively. If you want the algorithm to consider the first and last segments of the route at a special cost under the given restrictions, specify positive factors for them in the first_edges_penalty_factor and last_edges_penalty_factor fields for mileage on the first and last route segments, respectively.

For more information, see Route segment restrictions and Starting and end route segments.

Example

Locations are primarily in the center, north, and south of the city. The restriction of 15,000 m is set on the maximum distance between neighboring locations. In addition, increasing factors (first_edges_penalty_factor and last_edges_penalty_factor of 4) are specified.

This results in the employees' routes becoming more geographically grouped.

API request (JSON)API response

Assigning a location to an employee

To ensure that a location is always visited by the same employee, you can assign it to that employee using one of the following methods:

Assigning a location using tags

You need to set a unique tag for the employee in the tags field on the employees sheet. For all locations that must be assigned to this employee, you must specify this tag in the required_tags field on the locations sheet.

Example

Visits to 50 locations can be distributed among 5 employees. Locations 40 and 50 have a unique tag of employee3 in the required_tags field. Employee 3 has this tag in the tags field as well. As a result, visits to locations 40 and 50 are assigned to this employee.

API request (JSON)API response

Assigning a location using geofences

If you need to assign all locations in a certain area of the city to an employee, you can use allowed and forbidden geofences.

To allow only a specific employee to visit locations in a geofence, specify the geofence name on the employees sheet:

  • For the selected employee, in the allowed_zones field.
  • For other employees, in the forbidden_zones field.

You can add new geofences via the interface and the API.

Example

Visits to 50 locations can be distributed among 5 employees. There's a geofence called North, which includes locations in the north of Moscow. This geofence is specified in the allowed_zones field for employee 2 and in the forbidden_zones field for other employees. As a result, visits to all locations within the North geofence are planned for employee 2.

API request (JSON)API response

Workload balancing

During planning, locations aren't always evenly distributed among employees. To distribute the workload equally among employees, use the balancing parameters:

  1. Add the shipment_size.units field (estimating the labor costs per one visit to a location) to the locations sheet. Labor costs are estimated in units.

    Note

    If the handling time service_duration_s varies between locations, the estimation of labor costs shipment_size.units must be proportional to service_duration_s. For example, if you set service_duration_s = 1800 and shipment_size.units = 10 for a specific location, then the shipment_size.units value for service_duration_s = 3600 must be 20.

  2. Multiply shipment_size.units by visit_count for each location. You'll get an estimate of labor costs for all visits to the location within the planning period.

  3. Sum up values for all locations. Divide the total amount by the number of days within the planning period (the planning_days field on the options sheet). You'll get an estimate of the labor costs for all visits to the location per day.

  4. Divide the total daily estimate of the labor costs by the number of employees. You'll get the average workload per employee per day.

  5. Round up the resulting average workload and add extra 5–10 units. For example, if you get a value of 19.35, round it up to 20 and add 10 more units. The final result is 30 units. Add the capacity.units field to the employees sheet and specify the calculated value for all employees.

  6. On the employees sheet, specify the cost of one day of downtime (cost.empty_run) for each employee so that the algorithm takes all employees into account during planning. For example, cost.empty_run = 100,000.

The workload will be distributed evenly among all employees during planning.

Example 1

Visits to 20 locations must be distributed among 3 employees. The balancing parameters aren't set. As a result, visits to all locations are assigned to employee 2. Employees 1 and 3 remain unassigned.

API request (JSON)API response

Example 2

The same as in example 1, except this time the balancing parameters are set.

The labor costs for one visit to a location are estimated at 10 units. This value is indicated in the shipment_size.units field on the locations sheet. 2 visits are planned for each location: visit_count = 2.

The total labor cost estimate for all 20 locations is (10 * 2) * 20 = 400. This estimate is divided by the number of days within the planning period: 400 : 7 = 57.14.

The daily workload is distributed among 3 employees: 57.14 : 3 = 19.05. The value is rounded up and increased by 10, to 30 units. This estimate is specified for each employee in the capacity.units field on the employees sheet. The cost of one day of downtime is also set for each employee: cost.empty_run = 10,000.

As a result, visits to all locations are distributed evenly among all three employees.

API request (JSON)API response

Contact support