IBM ILOG Solver User's Manual > Evolutionary Algorithms > Introduction and Basic Concepts > Features of the library > Generation of the initial population

Any genetic algorithm begins by the generation of a suitable initial population. Our goal in this initial process is to create a set of solutions which have sufficient diversity. If you have a representation which is unconstrained (for instance, an indirect representation), then it is simple to create a completely random population. However, if this is not the case, the generation of the initial population becomes more subtle.

In Solver, the standard way of producing a solution is through the execution of a goal which instantiates the decision variables. In the EA Framework, the same technique can be applied repeatedly to generate an initial population. However, for the EA Framework, we need to be aware that Solver goals are completely deterministic; executing the same goal twice will produce exactly the same result. To avoid generating an initial population of identical solutions, we need to modify the behavior of the solution goal for each new population member.

The EA Framework provides a way of perturbing the normal behavior of a goal by altering its standard choices with a certain probability. This new goal can then be executed repeatedly to generate different solutions. A great advantage of this approach is that the probability can be controlled. By controlling the perturbation probability, the make-up of the population can be altered. When this probability is low, the solutions will resemble that generated by the unperturbed goal, but will be of reasonable quality if we assume that the standard goal is good. When high, solutions generated will be much more random in appearance, bearing little resemblance to the one generated by the standard goal. The resulting population is also likely to be lower in quality due to the large random element. Between the two extremes, a balance can be struck between diversity and quality.

Below, you will find two codes: one to generate a random solution pool and another to generate a solution pool from a randomly perturbed goal. Note that these code samples make use of a "prototype" solution. This prototype defines the structure for all solutions to be created; it has the correct decision variables and objective within it. The solutions to be included in the population are created by cloning the prototype. The notion of a solution prototype will also be used later.

Random solution:

IloIntVarArray vars = ...;
IloObjective obj = ...;
IloSolution prototype(env);
prototype.add(vars);
prototype.add(obj);

IloSolutionPool population(env);
IloRandom r = env.getRandom();
for (IloInt i = 0; i < popSize; i++) {
  IloSolution newMember = prototype.makeClone(env);
  for (IloInt j = 0; j < vars.getSize(); j++)
    newMember.setValue(vars[j], r.getInt(2));
  solver.solve(IloRestoreSolution(env, newMember)); // calculate objective
  newMember.store(solver);
  population.add(newMember);
}

Solution from goal:

IloIntVarArray vars = ...;
IloObjective obj = ...;
IloSolution prototype(env);
prototype.add(vars);
prototype.add(obj);
IloGoal generate = IloRandomPerturbation(env, stdGoal, 0.05);

IloSolutionPool population(env);
for (IloInt i = 0; i < popSize; i++) {
  while (!solver.solve(generate)) { }
  IloSolution newMember = prototype.makeClone(env);
  newMember.store(solver);
  population.add(newMember);
}

The goal modifier IloRandomPerturbation randomly modifies the branching decisions taken by stdGoal, such that (in this case) at each branch point, there is a 5% chance that the right branch will be taken before the left one, resulting in a slightly diversified population.