IBM ILOG Scheduler User's Manual > Advanced Concepts > Using The Trace Facilities to Relax a Model > Solving the Problem: Analyzing a Fail > Relaxing the Problem

As long as a solution is not found, the list scheduling algorithm is followed. In case of a failure, the fail result object is used to identify the guilty job. The deadline of the guilty job is then relaxed if it has not been previously relaxed. If the deadline has been previously relaxed, the job is removed from the model. If no guilty job is found by the trace analysis, another heuristic decision should be taken. To keep this example simple, we have not implemented such a decision.

    
    IloCPTrace initListSchedulingWithFailAnalysis = ListSchedulingWithFailAnalysis(env, analysisResult);
    solver.addTrace(initListSchedulingWithFailAnalysis);
    IloGoal goal = IloListScheduling(env);
    
    while (!solver.solve(goal)) {
      if (!analysisResult.hasGuiltyJob()) 
        throw Exception("Cannot give a solution to the problem");
      NewModelFromPartialSolution(analysisResult.getSolution());
      Job* guiltyJob = analysisResult.getGuiltyJob();
      if (!guiltyJob->isDeadlineRelaxed()) {
        guiltyJob->relaxDeadline();
        solver.out() << guiltyJob->getName() 
                     << " set at late deadline" << endl;
      } 
      else {
        guiltyJob->removeFromModel(model);
        solver.out() << guiltyJob->getName() 
                     << " removed from the model" << endl;
      }
    }
 

Every time we fail, we relax the problem and start again from the existing partial solution. We implement the restart by storing the partial solution in an IloSchedulerSolution object and using it to initialize the list scheduling solution after relaxing the problem. This initialization is performed in the function NewModelFromPartialSolution.

The initialization speeds up the construction of the list schedule for the new, relaxed model. We could assign the start times from the partial schedule; however, as we might be removing an already scheduled activity, such a policy might overly constrain the new schedule. Removing an already scheduled activity, for example, would result in a "hole" in the schedule that could be used to decrease the start time of another already scheduled activity. To avoid this problem, only the maximum start times of the activities of the partial schedule are fixed.

void NewModelFromPartialSolution(const IloSchedulerSolution& solution) {
  for(IloSchedulerSolution::ResourceIterator ite(solution);
      ite.ok(); 
      ++ite) {
    IloResource resource = *ite;
    if (resource.isUnaryResource() && 
        solution.hasPrecedenceInformation(resource)) {
      if (solution.hasSetupRC(resource)) {
        IloResourceConstraint rct = solution.getSetupRC(resource);
        for(;;) {
          IloActivity act = rct.getActivity();
          IloNum t = solution.getStartMin(act);
          act.setStartMax(t);
          if (solution.hasNextRC(rct))
            rct = solution.getNextRC(rct);
          else break;
        }
      }
    }
  }
}