IBM ILOG Scheduler User's Manual > Local Search in Scheduler > Tabu Search for the Jobshop Problem with Alternatives > Solving the Problem > Creating the Relocate Neighborhood

The relocate neighborhood defines a set of moves consisting of assigning each resource constraint on a randomly selected critical path to an alternative resource, inserting it between each pair of consecutive activities on that resource.

The implementation follows the same pattern as the N1 neighborhood implementation, inheriting from MyNHoodI and defining two methods: addMove and start. The former function is simple, as it creates an instance of RelocateRC and calls the MyNHoodI::realAddMove method.

  void addMove(IloSolver solver, 
               IloResourceConstraint relocate, IloResource to,
               IloResourceConstraint beforeInsertion) {
    RelocateRC *move = new (solver.getEnv()) 
      RelocateRC(relocate, to, beforeInsertion);
    MyNHoodI::realAddMove(move);
  }

The start method creates the set of neighbors from the given solution. For each resource constraint on the critical path, the set of alternative resources is iterated over and for each one, a set of moves is created. Each move inserts the original resource constraint between a pair of consecutive resource constraints on the alternative resource or as the first or last resource constraint on the resource.

void RelocateNHoodI::start(IloSolver solver, IloSolution soln) {
  MyNHoodI::start(solver, soln);
  
  IloInt cpSize = 0;
  IloArray<IloResourceConstraint> cpArray = _cp->computeCP(_solution, cpSize);
  
  // create the moves
  for(IloInt i = 0; i < cpSize; ++i) {
    IloResourceConstraint rc = cpArray[i];
    IloResource selected = _solution.getSelected(rc);
    if (rc.hasAltResSet()) {
      for(IloAltResSet::Iterator iter(rc.getAltResSet()); 
          iter.ok(); ++iter) {
        IloResource res = *iter;
        if (selected.getImpl() != res.getImpl()) {
 
          // add move to insert rc first on res
          addMove(solver, rc, res, 0);
          IloResourceConstraint prev = _solution.getSetupRC(res);
          while(prev.getImpl() != 0) {
            addMove(solver, rc, res, prev);
            prev = _solution.getNextRC(prev);
          }
        }
      }
    }
  }
}
 

Figure 28.1 shows part of the neighborhood of a solution, assuming that C1 and B1 are on the critical path that is chosen and that C1 can execute on either R0 or R1 and B1 can execute on either R1 or R2. There are five possible relocations of C1: between each consecutive pair of activities on R0 and as the first or last resource constraint on R0. Similarly, there are four possible relocations of B1. The neighborhood also contains the relocation moves of the other resource constraints on the chosen critical path (that is, C0 and B2).

tabuAlternativebr.gif

Figure 28.1 A Partial Neighborhood of a Solution