IBM ILOG Solver User's Manual > More on Modeling > Using Set Variables: Crew Scheduling > Model > Parameters of TeamConstraints

You have already declared the model and the array of set variables crews. The other parameters are arrays or elements of arrays that are also declared in the main function: crewSize, dataArrays, crewRequirements, and attributeSets.

crewSize

The array crewSize is declared in the main function. You declare an instance of the class IloNumArray with nCrews elements. The elements of this array are the crew size requirements for each flight. The following code is provided for you:

    IloNumArray crewSize(env, nCrews, 4, 5, 5, 6, 7, 4, 5, 6, 6, 7);

crewRequirements

The array crewRequirements is declared in the main function. You use the class IloArray to create an array of IloNumArray arrays. The array contains 10 arrays, one for each flight. Each element in the array crewRequirements is an array representing the crew requirements for each flight. Each array contains nAttributes elements, which is set to 5 in this example. The first element is the number of required senior staff members and is initialized to 1. The second element is the number of required junior staff members and is initialized to 1. The third element is the number of required French speakers. The fourth element is the number of required German speakers. The fifth element is the number of required Spanish speakers. These three elements are all initialized to 1 because each flight must contain at least one of the following: senior staff member, junior staff member, French speaker, German speaker, and Spanish speaker. A "for" loop is used to create the 10 arrays. The following code is provided:

    IloArray<IloNumArray> crewRequirements(env, nCrews);
    for (i =0; i < nCrews; i++)
      crewRequirements[i] = IloNumArray(env, nAttributes,
                                        1, 1, 1, 1, 1);

You use a C++ enumeration to associate meaningful names with the elements of the crewRequirements array. This code is provided:

    enum CrewRequirementsElements {SeniorSet, JuniorSet,
                                   FrenchSet, GermanSet, SpanishSet};

You adjust the crewRequirements arrays for those requirements that are not the same as the initialized defaults. For example, Flight #4 has a minimum senior staff requirement of 2, not 1. Therefore, you initialize the seniorSet element of crewRequirements[3] to 2. The code is provided for you:

      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;

attributeSets

The array of set variables attributeSets is declared in the main function. This is an array of sets that represents the experience levels and language skills of each flight attendant.

First, you create the attribute sets using the class IloNumSetVar. For example, you create the set of variables Senior with three parameters. The first parameter is the environment. The second parameter, the set of possible values, is the array SeniorArray. The elements of SeniorArray are all flight attendants with senior experience levels. The third parameter, the set of required values, is the same array SeniorArray. In effect, this means that SeniorArray and Senior contain the same exact elements. However, both the numeric array, SeniorArray, and the constrained set of variables, Senior, will be used in creating the constraints. Again, if you wanted to add another attribute, you would create a set representing the employees with that attribute. The following code is provided for you:

    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);

Next, you create the array of constrained set variables attributeSets. This array has nAttributes elements. The elements are the five sets of decision variables you just created. They will be used in creating constraints. The following code is provided:

    IloNumSetVarArray attributeSets(env, nAttributes, Senior, Junior,
                                    French, German, Spanish);

dataArrays

The array dataArrays is declared in the main function. You use the class IloArray to create an array of IloNumArray arrays. The elements of this array are the five arrays used to represent the experience levels and language skills of the employees. This is the same information as that represented by attributeSets. Both forms of this data, numeric arrays and set variables, are required to create the constraints. The array contains NumAttributes elements, which is set to 5 in this example. This array represents all the attributes. If you wanted to add another attribute, for example another language skill, you would have to create an array representing the flight attendants who had that skill and then add it to the array of arrays dataArrays. The following code is provided for you:

    IloArray<IloNumArray> dataArrays(env, nAttributes);
    dataArrays[0] = SeniorArray;
    dataArrays[1] = JuniorArray;
    dataArrays[2] = FrenchArray;
    dataArrays[3] = GermanArray;
    dataArrays[4] = SpanishArray; 

Now that you know what the parameters represent, you can add constraints to the TeamConstraints function. The first constraint states that the size of the crew should be equal to the crew size requirement for the flight. To do this, you use the function IloCard. This function constrains the number of elements in a set variable. You use IloCard to constrain the size of the set crews to equal CrewSize.

Step 6   -  

Add the constraint on crew size

Add the following code after the comment //Add the constraint on crew size

  model.add(IloCard(crews) == crewSize);

Next, you state the constraint that each crew must contain staff members that meet the requirements for experience level and language skills. To do this, you use the predefined constraint IloEqIntersection. This constraint takes four parameters, the environment and three sets of variables. The constraint forces the intersection of the sets var2 and var3 to be precisely the elements of the set intersection. Here is a constructor:

IloConstraint IloEqIntersection (const IloEnv env,
                                 const IloNumSetVar intersection,
                                 const IloNumSetVar var2,
                                 const IloNumSetVar var3);

The code works in a loop. The first time you take the intersection of two sets: the set of crew members for Flight #1 and the set Senior, representing all employees with a senior experience level. The intersection of these sets represents the Flight #1 crew members who have a senior experience level. You then add a constraint that the number of crew members in this intersection (Flight #1 crew members with a senior experience level) is greater than or equal to the crew requirements for senior staff on Flight #1. You then loop back and take the intersection of the set of crew members for Flight #1 and the set Junior, representing all employees with a junior experience level. The intersection of these sets represents the Flight #1 crew members who have a junior experience level. You add the constraint that the number of crew members in this intersection (Flight #1 crew members with a junior experience level) is greater than or equal to the crew requirements for junior staff on Flight #1. You continue looping until you have done this for all the crew requirements: senior experience level, junior experience level, French, German, and Spanish.

Step 7   -  

Add the constraints on crew requirements

Add the following code after the comment
//Add the constraints on crew requirements

  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]);
    }
}

The number of times you loop is determined by crewRequirements.getSize. If, for example, you call the TeamConstraints function for Flight #1, you would have the following scenario. The set of variables intersection has a possible set of the element of dataArrays. In the first loop, this element is dataArrays[0] or SeniorArray, an IloNumArray which consists of all flight attendants who have a senior experience level. You use IloEqIntersection to add the constraint that intersection is a set that contains elements that are in both the set crews (the crew for Flight # 1) and the set of the specified element of attributeSets. In the first loop, this element is attributeSets[0] or Senior, an IloNumSetVar which consists of all flight attendants who have a senior experience level. Then you add a constraint using IloCard, to state that the number of members in the set intersection must be greater than or equal to the specified element of crewRequirements. In the first loop, this element is crewRequirements[0] or, in the case of Flight #1, 1 (a minimum of 1 flight attendant with a senior experience level must be in the crew).

After you create the TeamConstraints function, you call it in the main function. A "for" loop is used to call the function 10 times, once for each flight.

Step 8   -  

Call the TeamConstraints function

Add the following code after the comment //Call the TeamConstraints function

    for(i=0; i< nCrews;i++)
      TeamConstraints(model, crews[i], crewSize[i],
                      crewRequirements[i], attributeSets, dataArrays);