/// <summary>
        /// Makes a solver named variable ranging over the values <paramref name="vmin"/>,
        /// <paramref name="vmax"/>, and the step <paramref name="vstep"/>. Returns the
        /// <see cref="IntVar"/> after it has been made.
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="vmin"></param>
        /// <param name="vmax"></param>
        /// <param name="vstep"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static IntVar MakeIntVar(this Solver solver, long vmin, long vmax, long vstep, string name)
        {
            var values = new CpInt64Vector();

            for (var v = vmin; v <= vmax; v += vstep)
                values.Add(v);

            return solver.MakeIntVar(values, name);
        }
        /// <summary>
        /// Makes a solver named variable ranging over the values <paramref name="vmin"/>,
        /// <paramref name="vmax"/>, and the step <paramref name="vstep"/>. Returns the
        /// <see cref="IntVar"/> after it has been made.
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="vmin"></param>
        /// <param name="vmax"></param>
        /// <param name="vstep"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static IntVar MakeIntVar(this Solver solver, long vmin, long vmax, long vstep, string name)
        {
            var values = new CpInt64Vector();

            for (var v = vmin; v <= vmax; v += vstep)
            {
                values.Add(v);
            }

            return(solver.MakeIntVar(values, name));
        }
Esempio n. 3
0
        protected RoutingModel ComposeRoutingModel(out List <int> failedNodes)
        {
            failedNodes = new List <int>();
            int numberOfSites = Data.GetTimeMatrix().GetLength(0);

            // Create Routing Model.
            // [START routing_model]
            RoutingModel routing = new RoutingModel(manager);
            // [END routing_model]

            // Define cost of each arc.
            // [START arc_cost]


            int transitCallbackIndex = routing.RegisterTransitCallback(timeCallback);

            routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
            // [END arc_cost]

            // Add Distance constraint.
            // [START time_constraint]
            // Documentation at: https://github.com/google/or-tools/blob/3494afff17d3dc60daf5ebe6ff2ab4cbc7777163/ortools/constraint_solver/routing.h#L383
            routing.AddDimension(
                transitCallbackIndex,            // transit callback
                Data.getAllowWaitingTime(),      // allow waiting time
                Data.getMaximumWorkerCapacity(), // vehicle maximum capacities
                false,                           // start cumul to zero
                "Time");
            RoutingDimension timeDimension = routing.GetMutableDimension("Time");

            // Add time window constraints for each location except depot
            // and 'copy' the slack var in the solution object (aka Assignment) to print it
            for (int i = 1; i < Data.GetTimeWindows().GetLength(0); ++i)
            {
                try
                {
                    long index = manager.NodeToIndex(i);
                    // TODO: To be replaced to allow mulible shifts similar to:
                    // https://gist.github.com/Muhammad-Altabba/5e52cc1aee98e88f11a01181341f630e#file-vrpsolver-py-L121
                    timeDimension.CumulVar(index).SetRange(
                        Data.GetTimeWindows()[i, 0],
                        Data.GetTimeWindows()[i, 1]);
                    routing.AddToAssignment(timeDimension.SlackVar(index));
                }
                catch (System.ApplicationException ex)
                {
                    //Possible cases: The site cannot be visited during the attendance time of the worker.
                    // Or the starting time is after the end time...
                    // Most likely a problem in timing for this node..
                    failedNodes.Add(i);
                    Console.WriteLine("(Note: " + ex.Message + " to add for node " + i + ". Could be because the site cannot be visited during the attendance time of the workers. Or there is a time inconsistency for this node.)");
                }
            }
            // Add time window constraints for each vehicle start node
            // and 'copy' the slack var in the solution object (aka Assignment) to print
            // it
            for (int i = 0; i < Data.GetVehicleNumber(); ++i)
            {
                long index = routing.Start(i);
                timeDimension.CumulVar(index).SetRange(
                    Data.GetTimeWindows()[0, 0],
                    Data.GetTimeWindows()[0, 1]);
                routing.AddToAssignment(timeDimension.SlackVar(index));
            }
            // [END time_constraint]

            for (int i = 0; i < numberOfSites; i++)
            {
                CpInt64Vector v = new CpInt64Vector();
                v.Add(manager.NodeToIndex(i));
                routing.AddDisjunction(v, Data.GetDemands()[i]);
            }
            return(routing);
        }