IBM ILOG Dispatcher User's Manual > Developing Dispatcher Applications > Developing Your Own Neighborhoods > Neighborhood Description > Defining the Neighborhood |
Defining the Neighborhood |
INDEX
![]() |
You begin by defining a neighborhood which exchanges the visit here
with each one of a set of predefined visits there
. You also declare other fields which are used internally: rsolution
holds the current solution and size
holds the size of the neighborhood (the number of neighbors). The fields prevHere
and nextHere
are used to hold the previous and next visits of here
in the current solution. The field vehHere
holds the vehicle performing the visit here
and the field perfHere
returns whether the visit here
is performed or not.
You then declare the methods for the new neighborhood class. You use a constructor which takes a visit to swap and an array of visits with which this "focus" visit can be swapped. Three virtual member functions of IloNHoodI
are also redefined: start
, define
, and getSize
. The latter is implemented inline.
The constructor of the subneighborhood builds the base class and installs the passed parameters.
LocalizedExchangeI::LocalizedExchangeI(IloEnv env, IloVisit visit, IloVisitArray arr) : IloNHoodI(env), _here(visit), _there(arr) { } |
The start
method is called by local search goals such as IloSingleMove
to indicate the current solution. You keep a reference to the current solution, which is cast into an IloRoutingSolution
for later use. (Casting the solution to an IloRoutingSolution
allows you to use API suitable for routing problems on the solution. Note that the solution itself is not altered in any way by this cast; it simply allows the use of a routing-based API on the solution.) The start
method also performs operations that need only to be done once. For example, you retrieve the following from the solution: the preceding and following visits of here
, the vehicle performing the visit here
, and whether or not the visit is performed. (If here
is not performed, the values of the other three pieces of information are later ignored.) You also calculate the size of the neighborhood, which is the size of the there
set. However, in order to be robust, you must set the size of the neighborhood to 0 if here
is not in the current solution (in which case it does not make sense to involve it in a move), or if the visit is not extracted (in which case attempting to move it will cause Solver to throw an exception later.)
The define
method is usually the main workhorse of any neighborhood definition. It takes an index and converts it to a solution delta. (The solution delta is a solution holding only the part of the current solution which needs to be changed, together with its new value.) This delta needs to be of type IloSolution
, not of type IloRoutingSolution
, although it can be cast to an IloRoutingSolution
to perform routing operations on it. The first thing you do in define
is to determine what the index signifies. (In other words, you determine to which swap the index corresponds.) This is easily done as here
is swapped with there[index]
. Then you perform various checks which allow you to ignore this neighbor in certain circumstances. Specifically, when the solution does not contain the visit there[index]
, or when this visit is not extracted, you can ignore the neighbor. Likewise, when both visits are unperformed (a swap is useless), or when both visits are served by the same vehicle (the move you define is only inter-route, but could be generalized), you ignore the neighbor. The neighbor is ignored by returning an empty handle (here you use return 0
to perform this action).
© Copyright IBM Corp. 1987, 2009. Legal terms. | PREVIOUS NEXT |