IBM ILOG Solver User's Manual > Evolutionary Algorithms > Car Sequencing Using EA > Problem solving: A genetic algorithm cycle |
Problem solving: A genetic algorithm cycle |
INDEX
![]() |
Once the initial population has been generated you can now move on to the construction of the genetic algorithm main loop; each cycle around the loop being termed a generation. Here, in each generation, only one new individual will be generated, and hence in this genetic algorithm, a system of replacement will be used; this will be described later.
First, an intensification method will be introduced. Here, constraint programming is used to improve the quality of the new solutions produced by the genetic algorithm. This is done by adding constraints on the cost which state that any produced solution must be better than the parent or parents that produced it. To avoid stagnation and stalling where it is very difficult to improve on a parent, the improvement rule is only applied probabilistically. Imagine two probabilities p and q. You will stipulate that the newly generated solution must be (strictly) better than the best parent with probability p, otherwise it must be strictly better than the worst parent with probability q. This enforcement is carried out via an operator.
Step 11 - | Add the improvement goal |
Add the following code after the comment // Improve on worst in input pool
The operator is relatively straightforward, deciding on limit
based on the best and worst solutions in the input pool (which will be the pool of parents when later used). A wrapper to produce an IloPoolProcessor
from this operator is provided for you.
The operator factory is now primed such that ImproveOn
is called before the invocation of any genetic operator generated by the factory.
Step 12 - | Create the parents solution pool |
Add the following code after the comment // Enforce probabilistic improvement
factory.setBeforeOperate(ImproveOn(env, 0.5, 0.9)); |
The operator dictates that with 50% chance a constraint is added which will insist that the offspring is better than the best parent, and with 45% chance that it is better than the worst parent. A 5% chance remains that the offspring can be equal in quality or worse than the worst parent.
You will now create the genetic operators to be used over the indirect representation.
Step 13 - | Create the selection of operators that will be used |
Add the following code after the comment // Create genetic operators
Here, a pool of processors is created. To this pool is added a mutation operator, which will mutate around two priorities each time it is applied, a uniform crossover operator, and a one-point crossover operator. A breeding operator is then created which applies a random selection of one of the above operators.
The breeding operator will produce a single offspring. After its application, a decision needs to be made on how this new solution is combined into the population: a replacement mechanism is needed. First, you will write the code for the use of the replacement, and then the details of its implementation will be examined.
Step 14 - | Replace the worst parent with the child and destroy this parent |
Add the following code after the comment // Child replaces worst parent
First, a pool to represent the parents selected for a genetic operator is created. Then, a selector is created which will both select a solution for destruction (producing it as output), and produce a side-effect on the population, removing the solution to be replaced and adding the solution that replaces it. The selector is passed the pool of parents because (as you will see) it operates by replacing one of the parent solutions in the population. The solution produced as output by replace
will then be destroyed by processor destroy
.
Before describing the replacement selector, you will see how all of the processors interact to produce one generation of the genetic algorithm.
Step 15 - | Create a pool processor |
Add the following code after the comment // Create single-generation processor
IloPoolProc cycle = pop >> rndSel >> parents >> breed(1) >> replaceAndDestroy; |
The flow is relatively self-explanatory: solutions are selected randomly from the population, and placed in the parents pool; these parents are then bred using an operator chosen at random from the three available; the new solution then replaces a member of the population and the replaced solution is destroyed.
A more subtle point is revealed if we ask ourselves: how do we know how many parents to select from the population? The mutation operator requires only one parent, but the crossover operators need two. This problem is resolved by the manner in which pool processor connection (via >>
) operates. Roughly speaking, control flow is right to left while data flow is left to right. This means that replaceAndDestroy
is invoked first, which then asks breed
for solutions. breed
then chooses one of the three available operators, from which it can work out the number of parents needed. It then asks rndSel
(indirectly, by passing via the parents
pool) for the correct number of parents, which are in turn fetched from pop
. At this point the selected solutions can flow back down the chain to the breed
pool which creates the offspring which will then be passed to replaceAndDestroy
to be merged with the population.
© Copyright IBM Corp. 1987, 2009. Legal terms. | PREVIOUS NEXT |