public static void makeDistanceTimeCapDims(Ivr8.Model m) { m.Dimensions = new Ivr8.DimensionConfiguration(); m.Dimensions.timeConfig = new Ivr8.InternalDimension { Id = "time", measurementUnit = Ivr8.InternalDimension.eMeasurementUnit.Minutes, slackMax = (float)1e6, tardyMax = 0 }; m.Dimensions.distanceConfig = new Ivr8.InternalDimension { Id = "distance", measurementUnit = Ivr8.InternalDimension.eMeasurementUnit.Kilometres, slackMax = 0, tardyMax = 0 }; m.Dimensions.capacityDimensions.Add( new Ivr8.CapacityDimension { Id = "capacity", Units = "kg", slackMax = 0, tardyMax = 0 } ); }
public static void makeJobTimeCap(Ivr8.Model m, List <dataRow> d, List <int> srcs, List <int> dests) { m.Jobs.Clear(); if (srcs.Count != dests.Count) { throw new System.Exception("Expected srcs.Count == dests.Count"); } for (int i = 0; i < srcs.Count; i++) { int si = srcs[i]; int di = dests[i]; Ivr8.Job j = new Ivr8.Job(); j.Id = "job_" + d[di].id; j.pickupTask = new Ivr8.Job.Task(); j.pickupTask.taskId = "pickup_" + d[di].id; j.pickupTask.locationId = d[si].id; j.pickupTask.Attributes.Add( new Ivr8.Job.Task.Attribute { dimensionId = "time", Quantity = d[di].pickupTime }); j.pickupTask.Attributes.Add( new Ivr8.Job.Task.Attribute { dimensionId = "capacity", Quantity = d[di].quanity } ); j.dropoffTask = new Ivr8.Job.Task(); j.dropoffTask.taskId = "dropoff_" + d[di].id; j.dropoffTask.locationId = d[di].id; // careful here, in C# the object is passed by ref. // so instantiate a new set of attributes, don't reuse the object's created // prior to this. j.dropoffTask.Attributes.Add( new Ivr8.Job.Task.Attribute { dimensionId = "time", Quantity = d[di].dropoffTime }); j.dropoffTask.Attributes.Add( new Ivr8.Job.Task.Attribute { dimensionId = "capacity", Quantity = -d[di].quanity } ); j.Penalty = 10000; m.Jobs.Add(j); } }
public static void makeLocations(Ivr8.Model m, List <dataRow> d) { m.Locations.Clear(); foreach (var l in d) { m.Locations.Add(new Ivr8.Location { Id = l.id, Geocode = new Ivr8.Geocode { Longitude = l.X, Latitude = l.Y } }); } }
public static void printCompartmentSummary(Ivr8.Model model, Ivr8.SolutionResponse solution) { Console.WriteLine("\nCompartment Summary:"); // for each vehicle, for each capacitated dimension create a template to populate for each column. // technically... we should be pulling the master list of compartments from the model, not the solution // response, but this method is quite nice looking the way it doesn't have a model as input. So we're going // to approximate the table here. int[] maxchar = new int[5] { "locationId".Length, "taskId".Length, "jobId".Length, "vehicleId".Length, "compartmentId".Length }; // column widths for Stopid locationId, taskId, jobId, vehicleId, compartmentId foreach (var r in solution.Routes) { maxchar[3] = Math.Max(maxchar[3], r.vehicleId.Length); foreach (var s in r.Stops) { maxchar[0] = Math.Max(maxchar[0], s.locationId.Length); maxchar[1] = Math.Max(maxchar[1], s.taskId.Length); maxchar[2] = Math.Max(maxchar[2], s.jobId.Length); maxchar[4] = Math.Max(maxchar[4], s.compartmentId.Length); } } Dictionary <string, Ivr8.CompartmentSet> vehicleCset = new Dictionary <string, Ivr8.CompartmentSet>(); foreach (var vc in model.vehicleClasses) { if (vc.compartmentSetId != "") { foreach (var v in model.Vehicles) { if (v.classId == v.classId) { vehicleCset[v.Id] = model.compartmentSets.Where(t => t.Id == vc.compartmentSetId).First(); } } } } foreach (var v in model.Vehicles) { if (v.compartmentSetId != "") { // then this overrides anything at the class level vehicleCset[v.Id] = model.compartmentSets.Where(t => t.Id == v.compartmentSetId).First(); } } Dictionary <string, Ivr8.Compartment> compartmentLookup = new Dictionary <string, Ivr8.Compartment>(); foreach (var c in model.Compartments) { compartmentLookup.Add(c.Id, c); } foreach (var r in solution.Routes) { if (r.Stops.Count > 2) { string vid = r.vehicleId; Dictionary <string, float> compartmentValues = new Dictionary <string, float>(); var cset = vehicleCset[vid]; foreach (var comp in cset.compartmentIds) { compartmentValues.Add(comp, 0); } HashSet <string> activeCaps = new HashSet <string>(); foreach (var c in cset.compartmentIds) { foreach (var capdim in compartmentLookup[c].Capacities) { activeCaps.Add(capdim.dimensionId); } } foreach (var dim in activeCaps) { Console.WriteLine("Vehicle: " + vid + " dimension:" + dim); string formatLine = "|{0,-8}|"; int nc = cset.compartmentIds.Count; object[] fargs = new object[nc + 4]; fargs[0] = ""; for (int i = 1; i <= nc; i++) { formatLine += ("{" + i + ",6}|"); fargs[i] = cset.compartmentIds[i - 1]; } fargs[nc + 1] = fargs[nc + 2] = fargs[nc + 3] = ""; formatLine += ("{" + (nc + 1) + "," + maxchar[1] + "}|"); // task formatLine += ("{" + (nc + 2) + "," + maxchar[3] + "}|"); // vehicle formatLine += ("{" + (nc + 3) + ",10}|"); // dimension Console.WriteLine(String.Format(formatLine, fargs)); // then we can just add a line for the compartment capacities fargs[0] = "capacity"; for (int i = 0; i < nc; i++) { fargs[i + 1] = (int)compartmentLookup[cset.compartmentIds[i]].Capacities.Where(q => q.dimensionId == dim).First().capacity; } fargs[nc + 1] = "taskId"; fargs[nc + 2] = "vehicleId"; fargs[nc + 3] = "dimension"; Console.WriteLine(String.Format(formatLine, fargs)); for (int si = 1; si < r.Stops.Count - 1; si++) { // skip the first and last stop because we know there is no compartment interaction there. var s = r.Stops[si]; if (s.compartmentId != "") { foreach (var a in s.Attributes) { if (a.dimId == dim) { compartmentValues[s.compartmentId] += (a.endValue - a.startValue); } } } // print the row after each update over the attributes. fargs[0] = "stop." + si; for (int i = 1; i <= nc; i++) { fargs[i] = (int)(compartmentValues[cset.compartmentIds[i - 1]]); } fargs[nc + 1] = s.taskId; fargs[nc + 2] = vid; fargs[nc + 3] = dim; Console.WriteLine(String.Format(formatLine, fargs)); } } } } }