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

Since we have two neighborhoods (one for swapping and one for relocating), we first create an abstract neighborhood class that inherits from IloNHoodI and which contains the functionality that is common to both concrete neighborhoods. In this case, the MyNHoodI class contains private and protected methods and data to manage the current solution, the set of possible moves, and the recalculation of the critical path and the previous pointers.

private:
  void resetCache()  { _cp->needsRecomputing(); }

protected:
  IloSchedulerSolution _solution;

  CriticalPath *_cp;

  IloArray<LSMove*> _moves;
  IloInt _nbMoves;

  void realAddMove(LSMove *m) {
    if (_nbMoves < _moves.getSize()) _moves[_nbMoves] = m;
    else _moves.add(m);
    _nbMoves++;
  }

The virtual methods inherited from IloNHoodI are also redefined. The start method stores the new solution and recalculates the previous pointers.

  void start(IloSolver, IloSolution soln) {
    _solution = IloSchedulerSolution(soln);
    _nbMoves = 0;
  }

The define and getSize methods are identical to what was implemented in the previous chapter as the LSMove subclass creates the delta solution and the size of the neighborhood is stored in the _nbMoves data member.

  IloSolution define(IloSolver solver, IloInt i) {
    return (_moves[i])->createDelta(solver.getEnv(), _solution);
  }

  IloInt getSize(IloSolver) const { return _nbMoves; }

Finally, the set of methods for maintaining the state of the neighborhood make use of the resetCache method described above.

  void notify(IloSolver, IloInt) { resetCache(); }
  void notifyOther (IloSolver, IloSolution) { resetCache(); }
  void reset() { _solution = 0; _nbMoves = 0; resetCache(); }