IBM ILOG Solver User's Manual > More on Modeling > Using Set Variables: Crew Scheduling > Complete program

The complete crews program follows. You can also view it online in the file YourSolverHome/examples/src/crews.cpp.

#include <ilsolver/ilosolverset.h>
ILOSTLBEGIN
 
void TeamConstraints(IloModel model,
                     const IloNumSetVar crews,
                     const IloNum crewSize,
                     const IloNumArray crewRequirements,
                     const IloNumSetVarArray attributeSets,
                     const IloArray<IloNumArray> dataArrays)  {
  IloEnv env = model.getEnv();
  model.add(IloCard(crews) == crewSize);
  IloInt size = crewRequirements.getSize();
  for (IloInt i = 0; i < size; i++) {
    IloNumSetVar intersection(env, dataArrays[i]);
    model.add(IloEqIntersection(env, intersection, crews, attributeSets[i]));
    model.add(IloCard(intersection) >= crewRequirements[i]);
    }
}
void Print(IloSolver solver, IloNumSetVar crews, char** Names) {
  for(IloNumSet::Iterator iter(solver.getIntSetValue(crews));iter.ok();++iter){
    solver.out() << Names[(IloInt)*iter] << " ";
  }
  solver.out() << endl;
}
int main() {
  IloEnv env;
  try {
    IloModel model(env);
    IloInt i;
    char* Names[20];
 
    for (i=0; i < 20; i++){
      Names[i]=new (env) char[10];
    }
    strcpy(Names[0],"Bill");
    strcpy(Names[1],"Bob");
    strcpy(Names[2],"Carol");
    strcpy(Names[3],"Carolyn");
    strcpy(Names[4],"Cathy");
    strcpy(Names[5],"David");
    strcpy(Names[6],"Ed");
    strcpy(Names[7],"Fred");
    strcpy(Names[8],"Heather");
    strcpy(Names[9],"Inez");
    strcpy(Names[10],"Janet");
    strcpy(Names[11],"Jean");
    strcpy(Names[12],"Jeremy");
    strcpy(Names[13],"Joe");
    strcpy(Names[14],"Juliet");
    strcpy(Names[15],"Marilyn");
    strcpy(Names[16],"Mario");
    strcpy(Names[17],"Ron");
    strcpy(Names[18],"Tom");
    strcpy(Names[19],"Tracy");
 
    enum Employee {Bill, Bob, Carol, Carolyn, Cathy,
                   David, Ed, Fred, Heather, Inez,
                   Janet, Jean, Jeremy, Joe, Juliet,
                   Marilyn, Mario, Ron, Tom, Tracy};
    IloNumArray Staff(env, 20,
                      Bill, Bob, Carol, Carolyn, Cathy,
                      David, Ed, Fred, Heather, Inez,
                      Janet, Jean, Jeremy, Joe, Juliet,
                      Marilyn, Mario, Ron, Tom, Tracy);
    
    const IloInt nAttributes = 5;
    const IloInt nCrews = 10;
    IloNumSetVarArray crews(env, nCrews);
    for(i = 0; i < nCrews; i++)
      crews[i] = IloNumSetVar(env, Staff);
    IloNumArray SeniorArray(env, 10,
                            Bill, Bob, Carol, Carolyn, Ed,
                            Fred, Janet, Marilyn, Mario, Tracy);
    IloNumArray JuniorArray(env, 10,
                            Cathy, David, Heather, Inez, Jean,
                            Jeremy, Joe, Juliet, Ron, Tom);
   
    IloNumArray FrenchArray(env, 5, Bill, Inez, Jean, Juliet, Ron);
    IloNumArray GermanArray(env, 5, Cathy, Jeremy, Juliet, Mario, Tom);
    IloNumArray SpanishArray(env, 7, Bill, Fred, Heather, Inez, Joe,
                             Marilyn, Mario);
 
    IloArray<IloNumArray> dataArrays(env, nAttributes);
    dataArrays[0] = SeniorArray;
    dataArrays[1] = JuniorArray;
    dataArrays[2] = FrenchArray;
    dataArrays[3] = GermanArray;
    dataArrays[4] = SpanishArray; 
 
    IloNumSetVar Senior(env, SeniorArray, SeniorArray);
    IloNumSetVar Junior(env, JuniorArray, JuniorArray);
    IloNumSetVar French(env, FrenchArray, FrenchArray);
    IloNumSetVar German(env, GermanArray, GermanArray);
    IloNumSetVar Spanish(env, SpanishArray, SpanishArray);
    IloNumArray crewSize(env, nCrews, 4, 5, 5, 6, 7, 4, 5, 6, 6, 7);
    IloNumSetVarArray attributeSets(env, nAttributes, Senior, Junior,
                                    French, German, Spanish);
 
    enum CrewRequirementsElements {SeniorSet, JuniorSet,
                                   FrenchSet, GermanSet, SpanishSet};
 
    IloArray<IloNumArray> crewRequirements(env, nCrews);
    for (i =0; i < nCrews; i++)
      crewRequirements[i] = IloNumArray(env, nAttributes,
                                        1, 1, 1, 1, 1);
      crewRequirements[3][SeniorSet] = 2;
      crewRequirements[3][JuniorSet] = 2;
      crewRequirements[3][FrenchSet] = 2;
      crewRequirements[3][SpanishSet] = 2;
      crewRequirements[4][SeniorSet] = 3;
      crewRequirements[4][JuniorSet] = 2;
      crewRequirements[4][FrenchSet] = 2;
      crewRequirements[4][SpanishSet] = 2;
      crewRequirements[8][SeniorSet] = 2;
      crewRequirements[8][JuniorSet] = 2;
      crewRequirements[9][SeniorSet] = 3;
      crewRequirements[9][JuniorSet] = 3;
    for(i=0; i< nCrews;i++)
      TeamConstraints(model, crews[i], crewSize[i],
                      crewRequirements[i], attributeSets, dataArrays);
    for(i = 0 ; i < nCrews-1 ; i++) {
      model.add(IloNullIntersect(env, crews[i], crews[i+1]));
      if (i < nCrews-2)
        model.add(IloNullIntersect(env, crews[i], crews[i+2]));
    }
 
    IloSolver solver(model);
    if (solver.solve(IloGenerate(env, crews))){
      solver.out() << "Solution" << endl;
      for (IloInt j=0 ; j< crews.getSize() ; j++) {
        solver.out() << "Crew #" << (j+1) << ": " ;
        Print(solver, crews[j], Names);
      }
    }
    else
      solver.out() << "No solution" << endl;
    solver.printInformation();
  }
  catch (IloException& ex) {
    cerr << "Error: " << ex << endl;
  }
  env.end();
  return 0;
}
 
 

Results

You should get the following results, though the information displayed by IloSolver::printInformation will vary depending on platform, machine, configuration, and so on.

Solution
Crew #1: Bill Bob Carol Cathy
Crew #2: Carolyn David Ed Fred Juliet
Crew #3: Heather Inez Janet Jeremy Joe
Crew #4: Bill Bob Carol Cathy Jean Marilyn
Crew #5: Carolyn David Ed Fred Juliet Mario Ron
Crew #6: Heather Inez Janet Jeremy
Crew #7: Bill Bob Carol Cathy Jean
Crew #8: Carolyn David Ed Fred Joe Juliet
Crew #9: Heather Inez Janet Jeremy Marilyn Mario
Crew #10: Bill Bob Carol Cathy Jean Ron Tom
Number of fails               : 8
Number of choice points       : 57
Number of variables           : 130
Number of constraints         : 232
Reversible stack (bytes)      : 20124
Solver heap (bytes)           : 112584
Solver global heap (bytes)    : 4044
And stack (bytes)             : 4044
Or stack (bytes)              : 4044
Search Stack (bytes)          : 4044
Constraint queue (bytes)      : 11152
Total memory used (bytes)     : 160036
Elapsed time since creation   : 0.09