private static void AddPickupAndDropoff(FeatureCollection run, RoutingModel routing) { const int pickup = 0, dropoff = 1; var groups = run .Features .Where(x => x.Properties.ContainsKey("orderId")) .GroupBy(x => x.Properties["orderId"]); foreach (var group in groups) { var pickupStop = group.Single(x => Convert.ToInt32(x.Properties["stopKind"]) == pickup); var dropoffStop = group.Single(x => Convert.ToInt32(x.Properties["stopKind"]) == dropoff); int pickupNode = run.Features.IndexOf(pickupStop), dropoffNode = run.Features.IndexOf(dropoffStop); // Set route precedence routing.AddPickupAndDelivery(pickupNode, dropoffNode); // Link same vehicle to both nodes var constraint = routing .solver() .MakeEquality( routing.VehicleVar(routing.NodeToIndex(pickupNode)), routing.VehicleVar(routing.NodeToIndex(dropoffNode))); routing.solver().Add(constraint); } }
private static void AddTimeDimension(FeatureCollection input, RoutingModel routing, NodeEvaluator2 evaluator) { var speed = 10 * 1000 / 3600; // 10 km/h routing.AddDimension(new ServiceTimeEvaluator(evaluator, speed), 24 * 3600, 24 * 3600, true, "Time"); var timeDimension = routing.GetDimensionOrDie("Time"); var timeWindow = 3600 * 3; for (int i = 0; i < input.Features.Count; i++) { var feature = input.Features[i]; if (feature.Properties.ContainsKey("start")) { int start = Convert.ToInt32(feature.Properties["start"]), end = start + timeWindow; timeDimension.CumulVar(routing.NodeToIndex(i)).SetRange(start, end); } } }