Generated on: Thu Mar 29 07:46:58 PDT 2012 for custom file set | ||
|
||
// doxy/ or-tools/ src/ constraint_solver/ |
00001 // Copyright 2010-2012 Google 00002 // Licensed under the Apache License, Version 2.0 (the "License"); 00003 // you may not use this file except in compliance with the License. 00004 // You may obtain a copy of the License at 00005 // 00006 // http://www.apache.org/licenses/LICENSE-2.0 00007 // 00008 // Unless required by applicable law or agreed to in writing, software 00009 // distributed under the License is distributed on an "AS IS" BASIS, 00010 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00011 // See the License for the specific language governing permissions and 00012 // limitations under the License. 00013 00014 // The vehicle routing library lets one model and solve generic vehicle routing 00015 // problems ranging from the Traveling Salesman Problem to more complex 00016 // problems such as the Capacitated Vehicle Routing Problem with Time Windows. 00017 // The objective of a vehicle routing problem is to build routes covering a set 00018 // of nodes minimizing the overall cost of the routes (usually proportional to 00019 // the sum of the lengths of each segment of the routes) while respecting some 00020 // problem-specific constraints (such as the length of a route). A route is 00021 // equivalent to a path connecting nodes, starting/ending at specific 00022 // starting/ending nodes. 00023 // The term "vehicle routing" is historical and the category of problems solved 00024 // is not limited to the routing of vehicles: any problem involving finding 00025 // routes visiting a given number of nodes optimally falls under this category 00026 // of problems, such as finding the optimal sequence in a playlist. 00027 // The literature around vehicle routing problems is extremelly dense but one 00028 // can find some basic introductions in the following links: 00029 // http://en.wikipedia.org/wiki/Travelling_salesman_problem 00030 // http://www.tsp.gatech.edu/history/index.html 00031 // http://en.wikipedia.org/wiki/Vehicle_routing_problem 00032 // 00033 // The vehicle routing library is a vertical layer above the constraint 00034 // programming library (constraint_programming:cp). 00035 // One has access to all underlying constrained variables of the vehicle 00036 // routing model which can therefore be enriched by adding any constraint 00037 // available in the constraint programming library. 00038 // There are two sets of variables available: 00039 // - path variables: 00040 // * "next(i)" variables representing the immediate successor of the node 00041 // corresponding to i; use IndexToNode() to get the node corresponding to 00042 // a "next" variable value; note that node indices are strongly typed 00043 // integers (cf. base/int-type.h); 00044 // * "vehicle(i)" variables representing the vehicle route to which the 00045 // node corresponding to i belongs; 00046 // * "active(i)" boolean variables, true if the node corresponding to i is 00047 // visited and false if not; this can be false when nodes are either 00048 // optional or part of a disjunction; 00049 // - dimension variables, used when one is accumulating quantities along routes, 00050 // such as weight or volume carried, distance or time: 00051 // * "cumul(i,d)" variables representing the quantity of dimension d when 00052 // arriving at the node corresponding to i; 00053 // * "transit(i,d)" variables representing the quantity of dimension d added 00054 // after visiting the node corresponding to i. 00055 // Solving the vehicle routing problems is mainly done using approximate methods 00056 // (namely local search, 00057 // cf. http://en.wikipedia.org/wiki/Local_search_(optimization)), potentially 00058 // combined with exact techniques based on dynamic programming and exhaustive 00059 // tree search. 00060 // 00061 // Advanced tips: Flags are available to tune the search used to solve routing 00062 // problems. Here is a quick overview of the ones one might want to modify: 00063 // - Limiting the search for solutions: 00064 // * routing_solution_limit (default: kint64max): stop the search after 00065 // finding 'routing_solution_limit' improving solutions; 00066 // * routing_time_limit (default: kint64max): stop the search after 00067 // 'routing_time_limit' milliseconds; 00068 // - Customizing search: 00069 // * routing_first_solution (default: select the first node with an unbound 00070 // successor and connect it to the first available node): selects the 00071 // heuristic to build a first solution which will then be improved by local 00072 // search; possible values are GlobalCheapestArc (iteratively connect two 00073 // nodes which produce the cheapest route segment), LocalCheapestArc (select 00074 // the first node with an unbound successor and connect it to the node 00075 // which produces the cheapest route segment), PathCheapestArc (starting 00076 // from a route "start" node, connect it to the node which produces the 00077 // cheapest route segment, then extend the route by iterating on the last 00078 // node added to the route). 00079 // * Local search neighborhoods: 00080 // - routing_no_lns (default: false): forbids the use of Large Neighborhood 00081 // Search (LNS); LNS can find good solutions but is usually very slow. 00082 // Refer to the description of PATHLNS in the LocalSearchOperators enum 00083 // in constraint_solver.h for more information. 00084 // - routing_no_tsp (default: true): forbids the use of exact methods to 00085 // solve "sub"-traveling salesman problems (TSPs) of the current model 00086 // (such as sub-parts of a route, or one route in a multiple route 00087 // problem). Uses dynamic programming to solve such TSPs with a maximum 00088 // size (in number of nodes) up to cp_local_search_tsp_opt_size (flag with 00089 // a default value of 13 nodes). It is not activated by default because it 00090 // can slow down the search. 00091 // * Meta-heuritics: used to guide the search out of local minima found by 00092 // local search. Note that, in general, a search with metaheuristics 00093 // activated never stops, therefore one must specify a search limit. 00094 // Several types of metaheuristics are provided: 00095 // - routing_guided_local_search (default: false): activates guided local 00096 // search (cf. http://en.wikipedia.org/wiki/Guided_Local_Search); 00097 // this is generally the most efficient metaheuristic for vehicle 00098 // routing; 00099 // - routing_simulated_annealing (default: false): activates simulated 00100 // annealing (cf. http://en.wikipedia.org/wiki/Simulated_annealing); 00101 // - routing_tabu_search (default: false): activates tabu search (cf. 00102 // http://en.wikipedia.org/wiki/Tabu_search). 00103 // 00104 // Code sample: 00105 // Here is a simple example solving a traveling salesman problem given a cost 00106 // function callback (returns the cost of a route segment): 00107 // 00108 // - Define a custom distance/cost function from a node to another; in this 00109 // example just returns the sum of the node indices (note the conversion from 00110 // the strongly-typed indices to integers): 00111 // 00112 // int64 MyDistance(RoutingModel::NodeIndex from, 00113 // RoutingModel::NodeIndex to) { 00114 // return (from + to).value(); 00115 // } 00116 // 00117 // - Create a routing model for a given problem size (int number of nodes) and 00118 // number of routes (here 1): 00119 // 00120 // RoutingModel routing(...number of nodes..., 1); 00121 // 00122 // - Set the cost function by passing a permanent callback to the distance 00123 // accessor here. The callback has the following signature: 00124 // ResultCallback2<int64, int64, int64>. 00125 // 00126 // routing.SetCost(NewPermanentCallback(MyDistance)); 00127 // 00128 // - Find a solution using Solve(), returns a solution if any (owned by 00129 // routing): 00130 // 00131 // const Assignment* solution = routing.Solve(); 00132 // CHECK(solution != NULL); 00133 // 00134 // - Inspect the solution cost and route (only one route here: 00135 // 00136 // LG << "Cost " << solution->ObjectiveValue(); 00137 // const int route_number = 0; 00138 // for (int64 node = routing.Start(route_number); 00139 // !routing.IsEnd(node); 00140 // node = solution->Value(routing.NextVar(node))) { 00141 // LG << routing.IndexToNode(node); 00142 // } 00143 // 00144 // More information on the usage of the routing library can be found here: 00145 // More information on the range of vehicle routing problems the library can 00146 // tackle can be found here: 00147 // Keywords: Vehicle Routing, Traveling Salesman Problem, TSP, VRP, CVRPTW, PDP. 00148 00149 #ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ 00150 #define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_ 00151 00152 #include <stddef.h> 00153 #include "base/hash.h" 00154 #include "base/hash.h" 00155 #include <string> 00156 #include <utility> 00157 #include <vector> 00158 00159 #include "base/callback-types.h" 00160 #include "base/commandlineflags.h" 00161 #include "base/integral_types.h" 00162 #include "base/macros.h" 00163 #include "base/scoped_ptr.h" 00164 #include "base/int-type-indexed-vector.h" 00165 #include "base/int-type.h" 00166 #include "base/hash.h" 00167 #include "constraint_solver/constraint_solver.h" 00168 00169 namespace operations_research { 00170 00171 class LocalSearchOperator; 00172 class RoutingCache; 00173 00174 // The type must be defined outside the class RoutingModel, SWIG does not parse 00175 // it correctly if it's inside. 00176 DEFINE_INT_TYPE(_RoutingModel_NodeIndex, int); 00177 00178 class RoutingModel { 00179 public: 00180 // First solution strategies, used as starting point of local search. 00181 enum RoutingStrategy { 00182 // Select the first node with an unbound successor and connect it to the 00183 // first available node. 00184 // This is equivalent to the CHOOSE_FIRST_UNBOUND strategy combined with 00185 // ASSIGN_MIN_VALUE (cf. constraint_solver.h). 00186 ROUTING_DEFAULT_STRATEGY, 00187 // Iteratively connect two nodes which produce the cheapest route segment. 00188 ROUTING_GLOBAL_CHEAPEST_ARC, 00189 // Select the first node with an unbound successor and connect it to the 00190 // node which produces the cheapest route segment. 00191 ROUTING_LOCAL_CHEAPEST_ARC, 00192 // Starting from a route "start" node, connect it to the node which produces 00193 // the cheapest route segment, then extend the route by iterating on the 00194 // last node added to the route. 00195 ROUTING_PATH_CHEAPEST_ARC, 00196 // Same as ROUTING_PATH_CHEAPEST_ARC, except that arc costs are evaluated 00197 // using the function passed to RoutingModel::SetFirstSolutionEvaluator(). 00198 ROUTING_EVALUATOR_STRATEGY, 00199 // Make all node inactive. Only finds a solution if nodes are optional (are 00200 // element of a disjunction constraint with a finite penalty cost). 00201 ROUTING_ALL_UNPERFORMED, 00202 // Iteratively build a solution by inserting nodes at their cheapest (best) 00203 // position. As of 2/2012, only works on models with optional nodes 00204 // (with finite penalty costs). 00205 ROUTING_BEST_INSERTION 00206 }; 00207 00208 // Metaheuristics used to guide the search. Apart greedy descent, they will 00209 // try to escape local minima. 00210 enum RoutingMetaheuristic { 00211 // Accepts improving (cost-reducing) local search neighbors until a local 00212 // minimum is reached. This is the default heuristic. 00213 ROUTING_GREEDY_DESCENT, 00214 // Uses guided local search to escape local minima 00215 // (cf. http://en.wikipedia.org/wiki/Guided_Local_Search); this is 00216 // generally the most efficient metaheuristic for vehicle routing. 00217 ROUTING_GUIDED_LOCAL_SEARCH, 00218 // Uses simulated annealing to escape local minima 00219 // (cf. http://en.wikipedia.org/wiki/Simulated_annealing). 00220 ROUTING_SIMULATED_ANNEALING, 00221 // Uses tabu search to escape local minima 00222 // (cf. http://en.wikipedia.org/wiki/Tabu_search). 00223 ROUTING_TABU_SEARCH 00224 }; 00225 00226 // Status of the search. 00227 enum Status { 00228 // Problem not solved yet (before calling RoutingModel::Solve()). 00229 ROUTING_NOT_SOLVED, 00230 // Problem solved successfully after calling RoutingModel::Solve(). 00231 ROUTING_SUCCESS, 00232 // No solution found to the problem after calling RoutingModel::Solve(). 00233 ROUTING_FAIL, 00234 // Time limit reached before finding a solution with RoutingModel::Solve(). 00235 ROUTING_FAIL_TIMEOUT 00236 }; 00237 00238 typedef _RoutingModel_NodeIndex NodeIndex; 00239 typedef ResultCallback2<int64, NodeIndex, NodeIndex> NodeEvaluator2; 00240 typedef std::vector<std::pair<int, int> > NodePairs; 00241 00242 // Constants with an index of the first node (to be used in for loops for 00243 // iteration), and a special index to signalize an invalid/unused value. 00244 static const NodeIndex kFirstNode; 00245 static const NodeIndex kInvalidNodeIndex; 00246 00247 // Supposes a single depot. A depot is the start and end node of the route of 00248 // a vehicle. 00249 RoutingModel(int nodes, int vehicles); 00250 // Constructor taking a vector of (start node, end node) pairs for each 00251 // vehicle route. Used to model multiple depots. 00252 RoutingModel(int nodes, 00253 int vehicles, 00254 const std::vector<std::pair<NodeIndex, NodeIndex> >& start_end); 00255 // Constructor taking vectors of start nodes and end nodes for each 00256 // vehicle route. Used to model multiple depots. 00257 // TODO(user): added to simplify SWIG wrapping. Remove when swigging 00258 // std::vector<std::pair<int, int> > is ok. 00259 RoutingModel(int nodes, 00260 int vehicles, 00261 const std::vector<NodeIndex>& starts, 00262 const std::vector<NodeIndex>& ends); 00263 ~RoutingModel(); 00264 00265 // Model creation 00266 00267 // Methods to add dimensions to routes; dimensions represent quantities 00268 // accumulated at nodes along the routes. They represent quantities such as 00269 // weights or volumes carried along the route, or distance or times. 00270 // Quantities at a node are represented by "cumul" variables and the increase 00271 // or decrease of quantities between nodes are represented by "transit" 00272 // variables. These variables are linked as follows: 00273 // if j == next(i), cumul(j) = cumul(i) + transit(i) + slack(i) 00274 // where slack is a positive slack variable (can represent waiting times for 00275 // a time dimension). 00276 00277 // Creates a dimension where the transit variable is constrained to be 00278 // equal to evaluator(i, next(i)); 'slack_max' is the upper bound of the 00279 // slack variable and 'capacity' is the upper bound of the cumul variables. 00280 // 'name' is the name used to reference the dimension; this name is used to 00281 // get cumul and transit variables from the routing model. 00282 void AddDimension(NodeEvaluator2* evaluator, 00283 int64 slack_max, 00284 int64 capacity, 00285 const string& name); 00286 // Creates a dimension where the transit variable is constrained to be 00287 // equal to 'value'; 'capacity' is the upper bound of the cumul variables. 00288 // 'name' is the name used to reference the dimension; this name is used to 00289 // get cumul and transit variables from the routing model. 00290 void AddConstantDimension(int64 value, int64 capacity, const string& name); 00291 // Creates a dimension where the transit variable is constrained to be 00292 // equal to 'values[i]' for node i; 'capacity' is the upper bound of 00293 // the cumul variables. 'name' is the name used to reference the dimension; 00294 // this name is used to get cumul and transit variables from the routing 00295 // model. 00296 void AddVectorDimension(const int64* values, 00297 int64 capacity, 00298 const string& name); 00299 // Creates a dimension where the transit variable is constrained to be 00300 // equal to 'values[i][next[i]' for node i; 'capacity' is the upper bound of 00301 // the cumul variables. 'name' is the name used to reference the dimension; 00302 // this name is used to get cumul and transit variables from the routing 00303 // model. 00304 void AddMatrixDimension(const int64* const* values, 00305 int64 capacity, 00306 const string& name); 00307 // Constrains all nodes to be active (to belong to a route). 00308 void AddAllActive(); 00309 // Adds a disjunction constraint on the nodes: exactly one of the nodes is 00310 // active. Start and end nodes of any vehicle cannot be part of a disjunction. 00311 void AddDisjunction(const std::vector<NodeIndex>& nodes); 00312 // Adds a penalized disjunction constraint on the nodes: at most one of the 00313 // nodes is active; if none are active a penalty cost is applied (this cost 00314 // is added to the global cost function). 00315 // This is equivalent to adding the constraint: 00316 // p + Sum(i)active[i] == 1, where p is a boolean variable 00317 // and the following cost to the cost function: 00318 // p * penalty. 00319 // "penalty" must be positive. 00320 // Note: passing a vector with a single node will model an optional node 00321 // with a penalty cost if it is not visited. 00322 void AddDisjunction(const std::vector<NodeIndex>& nodes, int64 penalty); 00323 #if defined(SWIGPYTHON) 00324 void AddDisjunctionWithPenalty(const std::vector<NodeIndex>& nodes, 00325 int64 penalty) { 00326 AddDisjunction(nodes, penalty); 00327 } 00328 #endif // SWIGPYTHON 00329 // Notifies that node1 and node2 form a pair of nodes which should belong 00330 // to the same route. This methods helps the search find better solutions, 00331 // especially in the local search phase. 00332 // It should be called each time you have an equality constraint linking 00333 // the vehicle variables of two node (including for instance pickup and 00334 // delivery problems): 00335 // Solver* const solver = routing.solver(); 00336 // solver->AddConstraint(solver->MakeEquality( 00337 // routing.VehicleVar(routing.NodeToIndex(node1)), 00338 // routing.VehicleVar(routing.NodeToIndex(node2)))); 00339 // solver->AddPickupAndDelivery(node1, node2); 00340 // 00341 // TODO(user): Remove this when model introspection detects linked nodes. 00342 void AddPickupAndDelivery(NodeIndex node1, NodeIndex node2) { 00343 pickup_delivery_pairs_.push_back(std::make_pair(NodeToIndex(node1), 00344 NodeToIndex(node2))); 00345 } 00346 // Makes 'depot' the starting node of all routes. 00347 void SetDepot(NodeIndex depot); 00348 // Sets the cost function of the model such that the cost of a segment of a 00349 // route between node 'from' and 'to' is evaluator(from, to), whatever the 00350 // route or vehicle performing the route. 00351 void SetCost(NodeEvaluator2* evaluator); 00352 // Sets the cost function for a given vehicle route. 00353 void SetVehicleCost(int vehicle, NodeEvaluator2* evaluator); 00354 // The fixed cost of a route is taken into account if the route is 00355 // not empty, aka there's at least one node on the route other than the 00356 // first and last nodes. 00357 // Gets the fixed cost of all vehicle routes if they are all the same; 00358 // otherwise returns the fixed cost of the first vehicle route. 00359 // Deprecated by GetVehicleFixedCost(). 00360 int64 GetRouteFixedCost() const; 00361 // Sets the fixed cost of all vehicle routes. It is equivalent to calling 00362 // SetVehicleFixedCost on all vehicle routes. 00363 void SetRouteFixedCost(int64 cost); 00364 // Returns the route fixed cost taken into account if the route of the 00365 // vehicle is not empty, aka there's at least one node on the route other than 00366 // the first and last nodes. 00367 int64 GetVehicleFixedCost(int vehicle) const; 00368 // Sets the fixed cost of one vehicle route. 00369 void SetVehicleFixedCost(int vehicle, int64 cost); 00370 00371 00372 // Search 00373 // Returns the strategy used to build a first solution. 00374 RoutingStrategy first_solution_strategy() const { 00375 return first_solution_strategy_; 00376 } 00377 // Sets the strategy used to build a first solution. 00378 void set_first_solution_strategy(RoutingStrategy strategy) { 00379 first_solution_strategy_ = strategy; 00380 } 00381 // Gets/sets the evaluator used when the first solution heuristic is set to 00382 // ROUTING_EVALUATOR_STRATEGY (variant of ROUTING_PATH_CHEAPEST_ARC using 00383 // 'evaluator' to sort node segments). 00384 #ifndef SWIG 00385 Solver::IndexEvaluator2* first_solution_evaluator() const { 00386 return first_solution_evaluator_.get(); 00387 } 00388 #endif 00389 // Takes ownership of evaluator. 00390 void SetFirstSolutionEvaluator(Solver::IndexEvaluator2* evaluator) { 00391 first_solution_evaluator_.reset(evaluator); 00392 } 00393 // If a first solution flag has been set (to a value different than Default), 00394 // returns the corresponding strategy, otherwise returns the strategy which 00395 // was set. 00396 RoutingStrategy GetSelectedFirstSolutionStrategy() const; 00397 // Adds a local search operator to the set of operators used to solve the 00398 // vehicle routing problem. 00399 void AddLocalSearchOperator(LocalSearchOperator* ls_operator); 00400 // Returns the metaheuristic used. 00401 RoutingMetaheuristic metaheuristic() const { return metaheuristic_; } 00402 // Sets the metaheuristic to be used. 00403 void set_metaheuristic(RoutingMetaheuristic metaheuristic) { 00404 metaheuristic_ = metaheuristic; 00405 } 00406 // If a metaheuristic flag has been set, returns the corresponding 00407 // metaheuristic, otherwise returns the metaheuristic which was set. 00408 RoutingMetaheuristic GetSelectedMetaheuristic() const; 00409 // Adds a search monitor to the search used to solve the routing model. 00410 void AddSearchMonitor(SearchMonitor* const monitor); 00411 // Closes the current routing model; after this method is called, no 00412 // modification to the model can be done, but RoutesToAssignment becomes 00413 // available. Note that CloseModel() is automatically called by Solve() and 00414 // other methods that produce solution. 00415 void CloseModel(); 00416 // Solves the current routing model; closes the current model. 00417 const Assignment* Solve(const Assignment* assignment = NULL); 00418 // Computes a lower bound to the routing problem solving a linear assignment 00419 // problem. The routing model must be closed before calling this method. 00420 // Note that problems with node disjunction constraints (including optional 00421 // nodes) and non-homogenous costs are not supported (the method returns 0 in 00422 // these cases). 00423 // TODO(user): Add support for non-homogeneous costs and disjunctions. 00424 int64 ComputeLowerBound(); 00425 // Returns the current status of the routing model. 00426 Status status() const { return status_; } 00427 // Applies a lock chain to the next search. 'locks' represents an ordered 00428 // vector of nodes representing a partial route which will be fixed during the 00429 // next search; it will constrain next variables such that: 00430 // next[locks[i]] == locks[i+1]. 00431 // Returns the next variable at the end of the locked chain; this variable is 00432 // not locked. An assignment containing the locks can be obtained by calling 00433 // PreAssignment(). 00434 IntVar* ApplyLocks(const std::vector<int>& locks); 00435 // Applies lock chains to all vehicles to the next search, such that locks[p] 00436 // is the lock chain for route p. Returns false if the locks do not contain 00437 // valid routes; expects that the routes do not contain the depots, 00438 // i.e. there are empty vectors in place of empty routes. 00439 // If close_routes is set to true, adds the end nodes to the route of each 00440 // vehicle and deactivates other nodes. 00441 // An assignment containing the locks can be obtained by calling 00442 // PreAssignment(). 00443 bool ApplyLocksToAllVehicles(const std::vector<std::vector<NodeIndex> >& locks, 00444 bool close_routes); 00445 // Returns an assignment used to fix some of the variables of the problem. 00446 // In practice, this assignment locks partial routes of the problem. This 00447 // can be used in the context of locking the parts of the routes which have 00448 // already been driven in online routing problems. 00449 const Assignment* const PreAssignment() const { return preassignment_; } 00450 // Writes the current solution to a file containing an AssignmentProto. 00451 // Returns false if the file cannot be opened or if there is no current 00452 // solution. 00453 bool WriteAssignment(const string& file_name) const; 00454 // Reads an assignment from a file and returns the current solution. 00455 // Returns NULL if the file cannot be opened or if the assignment is not 00456 // valid. 00457 Assignment* ReadAssignment(const string& file_name); 00458 // Restores an assignment as a solution in the routing model and returns the 00459 // new solution. Returns NULL if the assignment is not valid. 00460 Assignment* RestoreAssignment(const Assignment& solution); 00461 // Restores the routes as the current solution. Returns NULL if the solution 00462 // cannot be restored (routes do not contain a valid solution). 00463 // Note that calling this method will run the solver to assign values to the 00464 // dimension variables; this may take considerable amount of time, especially 00465 // when using dimensions with slack. 00466 Assignment* ReadAssignmentFromRoutes(const std::vector<std::vector<NodeIndex> >& routes, 00467 bool ignore_inactive_nodes); 00468 // Fills an assignment from a specification of the routes of the vehicles. The 00469 // routes are specified as lists of nodes that appear on the routes of the 00470 // vehicles. The indices of the outer vector in 'routes' correspond to 00471 // vehicles IDs, the inner vector contain the nodes on the routes for the 00472 // given vehicle. The inner vectors must not contain the start and end nodes, 00473 // as these are determined by the routing model. 00474 // Sets the value of NextVars in the assignment, adding the variables to the 00475 // assignment if necessary. The method does not touch other variables in the 00476 // assignment. The method can only be called after the model is closed. 00477 // With ignore_inactive_nodes set to false, this method will fail (return 00478 // NULL) in case some of the route contain nodes that are deactivated in the 00479 // model; when set to true, these nodes will be skipped. 00480 // Returns true if the route was successfully loaded. However, such assignment 00481 // still might not be a valid solution to the routing problem due to more 00482 // complex constraints; it is advisible to call solver()->CheckSolution() 00483 // afterwards. 00484 bool RoutesToAssignment(const std::vector<std::vector<NodeIndex> >& routes, 00485 bool ignore_inactive_nodes, 00486 bool close_routes, 00487 Assignment* const assignment) const; 00488 // Converts the solution in the given assignment to routes for all vehicles. 00489 // Expects that assignment contains a valid solution (i.e. routes for all 00490 // vehicles end with an end node for that vehicle). 00491 void AssignmentToRoutes(const Assignment& assignment, 00492 std::vector<std::vector<NodeIndex> >* const routes) const; 00493 // Returns a compacted version of the given assignment, in which all vehicles 00494 // with id lower or equal to some N have non-empty routes, and all vehicles 00495 // with id greater than N have empty routes. Does not take ownership of the 00496 // returned object. 00497 // If found, the cost of the compact assignment is the same as in the 00498 // original assignment and it preserves the values of 'active' variables. 00499 // Returns NULL if a compact assignment was not found. 00500 // This method only works in homogenous mode, and it only swaps equivalent 00501 // vehicles (vehicles with the same start and end nodes). When creating the 00502 // compact assignment, the empty plan is replaced by the route assigned to the 00503 // compatible vehicle with the highest id. Note that with more complex 00504 // constraints on vehicle variables, this method might fail even if a compact 00505 // solution exists. 00506 // This method changes the vehicle and dimension variables as necessary. 00507 // While compacting the solution, only basic checks on vehicle variables are 00508 // performed; the complete solution is checked at the end and if it is not 00509 // valid, no attempts to repair it are made (instead, the method returns 00510 // NULL). 00511 Assignment* CompactAssignment(const Assignment& assignment) const; 00512 // Adds an extra variable to the vehicle routing assignment. 00513 void AddToAssignment(IntVar* const var); 00514 00515 00516 // Model inspection. 00517 // Returns the variable index of the starting node of a vehicle route. 00518 int Start(int vehicle) const { return starts_[vehicle]; } 00519 // Returns the variable index of the ending node of a vehicle route. 00520 int End(int vehicle) const { return ends_[vehicle]; } 00521 // Returns true if 'index' represents the first node of a route. 00522 bool IsStart(int64 index) const; 00523 // Returns true if 'index' represents the last node of a route. 00524 bool IsEnd(int64 index) const { return index >= Size(); } 00525 int64 GetFirstSolutionCost(int64 i, int64 j); 00526 bool homogeneous_costs() const { return homogeneous_costs_; } 00527 // Assignment inspection 00528 // Returns the variable index of the node directly after the node 00529 // corresponding to 'index' in 'assignment'. 00530 int Next(const Assignment& assignment, int index) const; 00531 // Returns true if the route of 'vehicle' is non empty in 'assignment'. 00532 bool IsVehicleUsed(const Assignment& assignment, int vehicle) const; 00533 // Variables 00534 // Returns all next variables of the model, such that Nexts(i) is the next 00535 // variable of the node corresponding to i. 00536 IntVar** Nexts() const { return nexts_.get(); } 00537 // Returns all vehicle variables of the model, such that VehicleVars(i) is 00538 // the vehicle variable of the node corresponding to i. 00539 IntVar** VehicleVars() const { return vehicle_vars_.get(); } 00540 // Returns the next variable of the node corresponding to index. 00541 IntVar* NextVar(int64 index) const { return nexts_[index]; } 00542 // Returns the active variable of the node corresponding to index. 00543 IntVar* ActiveVar(int64 index) const { return active_[index]; } 00544 // Returns the vehicle variable of the node corresponding to index. 00545 IntVar* VehicleVar(int64 index) const { return vehicle_vars_[index]; } 00546 // Returns the cumul variable for the dimension named 'name'. 00547 IntVar* CumulVar(int64 index, const string& name) const; 00548 // Returns the transit variable for the dimension named 'name'. 00549 IntVar* TransitVar(int64 index, const string& name) const; 00550 // Returns the global cost variable which is being minimized. 00551 IntVar* CostVar() const { return cost_; } 00552 // Returns the cost of the segment between two nodes for a given vehicle 00553 // route. Input are variable indices of node. 00554 int64 GetCost(int64 from_index, int64 to_index, int64 vehicle); 00555 // Returns the cost of the segment between two nodes supposing all vehicle 00556 // costs are the same (returns the cost for the first vehicle otherwise). 00557 int64 GetHomogeneousCost(int64 i, int64 j) { 00558 return GetCost(i, j, 0); 00559 } 00560 00561 // Returns the underlying constraint solver. Can be used to add extra 00562 // constraints and/or modify search algoithms. 00563 Solver* solver() const { return solver_.get(); } 00564 00565 // Sizes and indices 00566 // Returns the number of nodes in the model. 00567 int nodes() const { return nodes_; } 00568 // Returns the number of vehicle routes in the model. 00569 int vehicles() const { return vehicles_; } 00570 // Returns the number of next variables in the model. 00571 int Size() const { return nodes_ + vehicles_ - start_end_count_; } 00572 // Returns the node index from an index value resulting fron a next variable. 00573 NodeIndex IndexToNode(int64 index) const; 00574 // Returns the variable index from a node value. 00575 // Should not be used for nodes at the start / end of a route, 00576 // because of node multiplicity. These cases return -1, which is 00577 // considered a failure case. Clients who need start and end 00578 // variable indices should use RoutingModel::Start and RoutingModel::End. 00579 int64 NodeToIndex(NodeIndex node) const; 00580 // Returns the variable indices of the nodes in the same disjunction as the 00581 // node corresponding to the variable of index 'index'. 00582 void GetDisjunctionIndicesFromIndex(int64 index, std::vector<int>* indices) const; 00583 00584 // Time limits 00585 // Returns the current time limit used in the search. 00586 int64 TimeLimit() const { return time_limit_ms_; } 00587 // Updates the time limit used in the search. 00588 void UpdateTimeLimit(int64 limit_ms); 00589 // Updates the time limit used in the Large Neighborhood search tree. 00590 void UpdateLNSTimeLimit(int64 limit_ms); 00591 00592 // Utilities for swig to set flags in python or java. 00593 void SetCommandLineOption(const string& name, const string& value); 00594 00595 private: 00596 typedef hash_map<string, IntVar**> VarMap; 00597 struct Disjunction { 00598 std::vector<int> nodes; 00599 int64 penalty; 00600 }; 00601 00602 struct CostCacheElement { 00603 NodeIndex node; 00604 int vehicle; 00605 int64 cost; 00606 }; 00607 00608 // Internal methods. 00609 void Initialize(); 00610 void SetStartEnd(const std::vector<std::pair<NodeIndex, NodeIndex> >& start_end); 00611 void AddDisjunctionInternal(const std::vector<NodeIndex>& nodes, int64 penalty); 00612 void AddNoCycleConstraintInternal(); 00613 void SetVehicleCostInternal(int vehicle, NodeEvaluator2* evaluator); 00614 Assignment* DoRestoreAssignment(); 00615 // Variants of GetCost and GetHomogeneousCost returning costs used in local 00616 // search filters. 00617 int64 GetFilterCost(int64 i, int64 j, int64 vehicle); 00618 int64 GetHomogeneousFilterCost(int64 i, int64 j) { 00619 return GetFilterCost(i, j, 0); 00620 } 00621 // Returns NULL if no penalty cost, otherwise returns penalty variable. 00622 IntVar* CreateDisjunction(int disjunction); 00623 // Returns the first active node in nodes starting from index + 1. 00624 int FindNextActive(int index, const std::vector<int>& nodes) const; 00625 00626 // Checks that all nodes on the route starting at start_index (using the 00627 // solution stored in assignment) can be visited by the given vehicle. 00628 bool RouteCanBeUsedByVehicle(const Assignment& assignment, 00629 int start_index, 00630 int vehicle) const; 00631 // Replaces the route of unused_vehicle with the route of active_vehicle in 00632 // compact_assignment. Expects that unused_vehicle is a vehicle with an empty 00633 // route and that the route of active_vehicle is non-empty. Also expects that 00634 // 'assignment' contains the original assignment, from which 00635 // compact_assignment was created. 00636 // Returns true if the vehicles were successfully swapped; otherwise, returns 00637 // false. 00638 bool ReplaceUnusedVehicle(int unused_vehicle, 00639 int active_vehicle, 00640 Assignment* compact_assignment) const; 00641 00642 NodeEvaluator2* NewCachedCallback(NodeEvaluator2* callback); 00643 Solver::IndexEvaluator3* BuildCostCallback(); 00644 void CheckDepot(); 00645 void QuietCloseModel() { 00646 if (!closed_) { 00647 CloseModel(); 00648 } 00649 } 00650 // Sets up search objects, such as decision builders and monitors. 00651 void SetupSearch(); 00652 // Set of auxiliary methods used to setup the search. 00653 // TODO(user): Document each auxiliary method. 00654 Assignment* GetOrCreateAssignment(); 00655 SearchLimit* GetOrCreateLimit(); 00656 SearchLimit* GetOrCreateLocalSearchLimit(); 00657 SearchLimit* GetOrCreateLargeNeighborhoodSearchLimit(); 00658 LocalSearchOperator* CreateInsertionOperator(); 00659 LocalSearchOperator* CreateNeighborhoodOperators(); 00660 const std::vector<LocalSearchFilter*>& GetOrCreateLocalSearchFilters(); 00661 DecisionBuilder* CreateSolutionFinalizer(); 00662 DecisionBuilder* CreateFirstSolutionDecisionBuilder(); 00663 LocalSearchPhaseParameters* CreateLocalSearchParameters(); 00664 DecisionBuilder* CreateLocalSearchDecisionBuilder(); 00665 void SetupDecisionBuilders(); 00666 void SetupMetaheuristics(); 00667 void SetupAssignmentCollector(); 00668 void SetupTrace(); 00669 void SetupSearchMonitors(); 00670 00671 IntVar** GetOrMakeCumuls(int64 capacity, const string& name); 00672 IntVar** GetOrMakeTransits(NodeEvaluator2* evaluator, 00673 int64 slack_max, 00674 int64 capacity, 00675 const string& name); 00676 00677 int64 GetArcCost(int64 i, int64 j, int64 vehicle); 00678 int64 GetPenaltyCost(int64 i) const; 00679 int64 WrappedEvaluator(NodeEvaluator2* evaluator, 00680 int64 from, 00681 int64 to); 00682 00683 // Model 00684 scoped_ptr<Solver> solver_; 00685 Constraint* no_cycle_constraint_; 00686 scoped_array<IntVar*> nexts_; 00687 scoped_array<IntVar*> vehicle_vars_; 00688 scoped_array<IntVar*> active_; 00689 std::vector<NodeEvaluator2*> costs_; 00690 bool homogeneous_costs_; 00691 std::vector<CostCacheElement> cost_cache_; 00692 std::vector<RoutingCache*> routing_caches_; 00693 std::vector<Disjunction> disjunctions_; 00694 hash_map<int64, int> node_to_disjunction_; 00695 NodePairs pickup_delivery_pairs_; 00696 IntVar* cost_; 00697 std::vector<int64> fixed_costs_; 00698 int nodes_; 00699 int vehicles_; 00700 std::vector<NodeIndex> index_to_node_; 00701 ITIVector<NodeIndex, int> node_to_index_; 00702 std::vector<int> index_to_vehicle_; 00703 std::vector<int> starts_; 00704 std::vector<int> ends_; 00705 int start_end_count_; 00706 bool is_depot_set_; 00707 VarMap cumuls_; 00708 VarMap transits_; 00709 hash_map<string, Solver::IndexEvaluator2*> transit_evaluators_; 00710 bool closed_; 00711 Status status_; 00712 00713 // Search data 00714 RoutingStrategy first_solution_strategy_; 00715 scoped_ptr<Solver::IndexEvaluator2> first_solution_evaluator_; 00716 RoutingMetaheuristic metaheuristic_; 00717 std::vector<SearchMonitor*> monitors_; 00718 SolutionCollector* collect_assignments_; 00719 DecisionBuilder* solve_db_; 00720 DecisionBuilder* improve_db_; 00721 DecisionBuilder* restore_assignment_; 00722 Assignment* assignment_; 00723 Assignment* preassignment_; 00724 std::vector<IntVar*> extra_vars_; 00725 std::vector<LocalSearchOperator*> extra_operators_; 00726 std::vector<LocalSearchFilter*> filters_; 00727 00728 int64 time_limit_ms_; 00729 int64 lns_time_limit_ms_; 00730 SearchLimit* limit_; 00731 SearchLimit* ls_limit_; 00732 SearchLimit* lns_limit_; 00733 00734 // Callbacks to be deleted 00735 hash_set<NodeEvaluator2*> owned_node_callbacks_; 00736 hash_set<Solver::IndexEvaluator2*> owned_index_callbacks_; 00737 00738 DISALLOW_COPY_AND_ASSIGN(RoutingModel); 00739 }; 00740 00741 } // namespace operations_research 00742 00743 #endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_H_