IBM ILOG Scheduler User's Manual > Advanced Concepts > Using The Trace Facilities to Relax a Model > Defining the Problem, Designing a Model > Jobs and Activities

A new class Job is used to represent the activities and the constraints associated with the processing of a product (either product A or B). The data member _jobModel stores all the precedence and time-bound constraints related to the activities of the job. This job model is very useful for adding and removing jobs--the activities plus all the related constraints--to and from the problem model. This is done with the member functions addToModel and removeFromModel.

class Job {
private:
  IloModel _jobModel;
  IloIntVar _deadline;
  IloBool _isDeadlineRelaxed;
public:
  Job(const IloEnv env, const char* name, IloInt deadline);
  void addToModel(IloModel model) { model.add(_jobModel); }
  void removeFromModel(IloModel model) { model.remove(_jobModel); }
  void relaxDeadline();
  IloBool isDeadlineRelaxed() const { return _isDeadlineRelaxed; }
  const char* getName() const { return _jobModel.getName(); }
protected:
  IloIntVar getDeadlineVar() const { return _deadline; }
  IloModel getJobModel() const { return _jobModel; }
};
 

When a job is created, its deadline (the delivery date of the product) is not relaxed. The member function relaxDeadline can be used to relax it in the job model.

Job::Job(const IloEnv env,
         const char* name,
         IloInt deadline) 
 : _jobModel(env, name),
   _deadline(env),
   _isDeadlineRelaxed(IlcFalse)
{
  _deadline.setLB(deadline);
  _deadline.setUB(deadline);
}
 
void Job::relaxDeadline() {
  if (!_isDeadlineRelaxed) {
    IloInt deadline = (IloInt)_deadline.getUB() + DeadlineExtension;
    _isDeadlineRelaxed = IlcTrue;
    _deadline.setLB(deadline);
    _deadline.setUB(deadline);
  }
}
 

The two classes JobA and JobB are subclasses of Job. In their respective constructors, the classes specify the constraints that define the job and add those constraints to the job model. Some objects are also added to the IloSchedulerSolution object. These will be used later in the analysis of the partial solutions.

// JOB A CLASS
 
class JobA : public Job {
public:
  JobA(const IloEnv env, const char* name, IloInt deadline, 
       IloSchedulerSolution solution, IloUnaryResource* workers);
};
 
JobA::JobA(const IloEnv env, const char* name, IloInt deadline, 
           IloSchedulerSolution solution, IloUnaryResource* workers) 
: Job(env, name, deadline) {
  IloInt i;
  IloModel jobModel = getJobModel();
  IloInt numberOfActivities = 4;
  IloActivity* act = new (env) IloActivity[numberOfActivities];
  char buffer[128];
  for(i=0; i < numberOfActivities; i++) {
    sprintf(buffer, "%s(Act%ld)", name, i);
    act[i] = IloActivity(env, 1, buffer);
    act[i].setObject(this);
    IloResourceConstraint ct = act[i].requires(workers[i]);
    jobModel.add(ct);
    solution.add(act[i]);
    solution.add(ct);
  }
  jobModel.add(act[3].endsBefore(getDeadlineVar()));
  jobModel.add(act[1].startsAfterEnd(act[0]));
  jobModel.add(act[2].startsAfterEnd(act[0]));
  jobModel.add(act[3].startsAfterEnd(act[1]));
  jobModel.add(act[3].startsAfterEnd(act[2]));
}
 
// JOB B CLASS
 
class JobB : public Job {
public:
  JobB(const IloEnv env, const char* name, IloInt deadline, 
       IloSchedulerSolution solution, IloAltResSet* teams);
};
 
JobB::JobB(const IloEnv env, const char* name, IloInt deadline, 
           IloSchedulerSolution solution, IloAltResSet* teams) 
: Job(env, name, deadline) {
  IloInt i;
  IloModel jobModel = getJobModel();
  IloInt numberOfActivities = 2;
  IloActivity* act = new (env) IloActivity[numberOfActivities];
  char buffer[128];
  for(i=0; i < numberOfActivities; i++) {
    sprintf(buffer, "%s(Act%ld)", name, i);
    act[i] = IloActivity(env, 2, buffer);
    act[i].setObject(this);
    IloResourceConstraint ct = act[i].requires(teams[i]);
    jobModel.add(ct);
    solution.add(act[i]);
    solution.add(ct);
  }
  jobModel.add(act[1].endsBefore(getDeadlineVar()));
  jobModel.add(act[1].startsAfterEnd(act[0]));
}
 

Notice that the job instance is linked to each activity. When we handle an activity, it is easy to get the job to which it belongs by calling getJob.

Job* getJob(IloActivity act) {
  return (Job*)act.getObject();
}

Job* getJob(IlcActivity act) {
  return (Job*)act.getObject();
}