IBM ILOG Solver User's Manual > Extending the Library > Writing a Constraint: Allocating Frequencies > Writing a constraint: Frequency allocation > Main program

The main program is straightforward. It uses a single array to represent all the variables, so "housekeeping" is simple. To access these variables, there are only two features: the function acc and the partialsum array. Apart from that, the program simply sets the constraints deterministically using IloAbs, as mentioned before.

The function acc accesses a two-dimensional array representing the channels for each cell. The first index denotes the cell number. Since the number of channels per cell varies, the number of elements in each row in the two-dimensional array varies as well. Consequently, the jth element in row i has a partial sum as its index, partialSum[i]+j, where partialSum[i] is defined recursively, like this:

In the loops in this program, the indexes i, j, ii, and jj indicate that for each pair (i, j) of cells, and for each channel ii of i and jj of j, the distance constraint holds between such two channels (taken from the distance matrix).

You can see the entire program online in the file freq.cpp. The main program follows:

IlcInt partialsum[nbCell];
inline IlcInt acc(IlcInt i, IlcInt j) {
  return partialsum[i]+j;
}
 
int main(){
  IloEnv env;
  try {
    IloModel model(env);
    IloSolver solver(env);
 
    IlcInt i, ii, j, jj;
    IlcInt usedFreq = 0;
    IlcInt nbXmiter = 0;
 
    for (i = 0; i < nbCell; i++) {
      partialsum[i] = nbXmiter;
      nbXmiter += nbChannel[i];
    }
 
    IloIntVarArray X(env, nbXmiter, 0, nbAvailFreq - 1);
 
    for (i = 0; i < nbCell; i++)
      for (j = i; j < nbCell; j++)
        for (ii = 0; ii < nbChannel[i]; ii++)
          for (jj = 0; jj < nbChannel[j]; jj++)
            if (dist[i][j] != 0 && (i != j || ii != jj))
              model.add(IloAbs(X[acc(i,ii)] - X[acc(j,jj)]) >= dist[i][j]);
 
    model.add(IloFreqConstraint(env, X));
 
    solver.extract(model);
 
    for (i = 0; i < nbCell; i++)
      for (ii = 0; ii < nbChannel[i]; ii++)
        SetCluster(solver.getIntVar(X[acc(i,ii)]), nbChannel[i]);
 
    freqUsage = new (env) IlcRevInt* [nbAvailFreq];
    for (i = 0; i < nbAvailFreq; i++)
      freqUsage[i] = new (env) IlcRevInt(solver);
 
    solver.solve(MyIloGenerate(env, X));
 
    for (i = 0; i < nbCell; i++) {
      for (j = 0; j < nbChannel[i]; j++)
        solver.out() << solver.getValue(X[acc(i,j)]) << "  " ;
      solver.out() << endl;
    }
    solver.out() << "Total # of sites       " << nbXmiter << endl;
    for (i = 0; i < nbAvailFreq; i++)
      if (freqUsage[i]->getValue() != 0)
        usedFreq++;
    solver.out() << "Total # of frequencies " << usedFreq << endl;
  }
  catch (IloException& ex) {
    cout << "Error: " << ex << endl;
  }
  env.end();
  return 0;
}