/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: CycleCrossoverFavoringStrongParents.java
* Written by Team 3: Christian Wittner
*
* This code has been developed at the Karlsruhe Institute of Technology (KIT), Germany,
* as part of the course "Multicore Programming in Practice: Tools, Models, and Languages".
* Contact instructor: Dr. Victor Pankratius (pankratius@ipd.uka.de)
*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*
* Electric(tm) is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Electric(tm) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Electric(tm); see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, Mass 02111-1307, USA.
*/
package com.sun.electric.tool.placement.genetic1.g1;
import com.sun.electric.tool.placement.genetic1.Chromosome;
import com.sun.electric.tool.placement.genetic1.Crossover;
import com.sun.electric.tool.placement.genetic1.Population;
import java.util.ArrayList;
import java.util.Random;
/**
* Implement Cycle Crossover.
*/
public class CycleCrossoverFavoringStrongParents implements Crossover {
float crossOverRate;
Random r;
boolean isPositionUsed[];
// mappings from genePosToNodeIndex
int[] P1genePosToNodeIndex;
int[] P2genePosToNodeIndex;
/**
*
* @param crossOverRate
*/
public CycleCrossoverFavoringStrongParents(float crossOverRate, Random r,
int chromsomeSize) {
this.crossOverRate = crossOverRate;
this.r = r;
isPositionUsed = new boolean[chromsomeSize];
P1genePosToNodeIndex = new int[chromsomeSize];
P2genePosToNodeIndex = new int[chromsomeSize];
}
public void crossover(Population population) {
assert (r != null) : "set random seed value before first use";
int indexOfProxy;
int nbrOfCrossovers = Math.round(population.chromosomes.size() * crossOverRate);
int nbrOfGenesPerChromsome = GeneticPlacement.nodeProxies.length;
ArrayList<Chromosome> offsprings = new ArrayList<Chromosome>(
nbrOfCrossovers);
// chromosomes representing parents
Chromosome[] P1 = new Chromosome[nbrOfCrossovers];
Chromosome[] P2 = new Chromosome[nbrOfCrossovers];
Chromosome swapChromosome, offspring;
// select parents for offsprings favoring strong individuals
double sumOfAllFitnessValues = 0.0;
for (Chromosome c : population.chromosomes)
sumOfAllFitnessValues += (1 / c.fitness.doubleValue());
for (int i = 0; i < nbrOfCrossovers; i++) {
// generate random value between 0 and sumOfAllFitnessValues
double canidateSelector = r.nextDouble() * sumOfAllFitnessValues;
// get P1
double currentFitnessSum = 0.0;
for (Chromosome c : population.chromosomes) {
currentFitnessSum += (1 / c.fitness.doubleValue());
if (currentFitnessSum >= canidateSelector) {
P1[i] = c;
break;
}
}
// get P2
canidateSelector = r.nextDouble() * sumOfAllFitnessValues;
currentFitnessSum = 0.0;
for (Chromosome c : population.chromosomes) {
currentFitnessSum += (1 / c.fitness.doubleValue());
if (currentFitnessSum >= canidateSelector) {
// if we just picked P1 again get next
if (P1[i] == c) {
int indexOfC = population.chromosomes.indexOf(c);
// if c is last in list get first element
if (indexOfC == population.chromosomes.size() - 1) {
P2[i] = population.chromosomes.get(0);
} else {
// just pick next in liste
P2[i] = population.chromosomes.get(
indexOfC + 1);
}
} else {
P2[i] = c;
break;
}
}
}
}
int[] swapIndex;
// while nbr of crossovers < crossover rate
for (int i = 0; i < nbrOfCrossovers; i++) {
assert (P1[i] != null);
assert (P2[i] != null);
assert (P1[i] != P2[i]);
// create new chromsome to represent offspring
// TODO:later get from object pool
offspring = new Chromosome(nbrOfGenesPerChromsome);
// calculate genePos2NodeIndexMap for P1 and P2
// TODO: this proves that generateGenePos2IndexMapping method is not
// well placed in GenePlacementLeftAlignedDrop
// eventually we can computer this reverse mapping only if required
// and
// save it for further use.
// computation vs memory resource!
GenePlacementLeftRightAlignedDrop.generateGenePos2IndexMapping(
P1[i].Index2GenePositionInChromosome, P1genePosToNodeIndex);
GenePlacementLeftRightAlignedDrop.generateGenePos2IndexMapping(
P2[i].Index2GenePositionInChromosome, P2genePosToNodeIndex);
// fill list with all available indices
for (int ind = 0; ind < isPositionUsed.length; ind++)
isPositionUsed[ind] = false;
int nbrOfPlacedNodes = 0;
// for all nodes to place in offspring
while (nbrOfPlacedNodes < isPositionUsed.length)
// cycle crossover
{
// randomly select cell to be placed
indexOfProxy = r.nextInt(isPositionUsed.length);
while (isPositionUsed[indexOfProxy]) {
indexOfProxy++;
if (indexOfProxy == isPositionUsed.length)
indexOfProxy = 0;
}
while (true) {
// get gene position in P1
// put it into P1's position in the offspring
offspring.Index2GenePositionInChromosome[indexOfProxy] = P1[i].Index2GenePositionInChromosome[indexOfProxy];
isPositionUsed[indexOfProxy] = true;
nbrOfPlacedNodes++;
offspring.GeneRotation[indexOfProxy] = P1[i].GeneRotation[indexOfProxy];
offspring.GeneXPadding[indexOfProxy] = P1[i].GeneXPadding[indexOfProxy];
offspring.GeneYPadding[indexOfProxy] = P1[i].GeneYPadding[indexOfProxy];
// get node at this position from P2
indexOfProxy = P2genePosToNodeIndex[P1[i].Index2GenePositionInChromosome[indexOfProxy]];
// if it is already in the offspring the current cycle is
// finished
if (isPositionUsed[indexOfProxy])
break;
}// cycle ended
// swap P1 and P2 to start the next cycle from the other
// parent
swapChromosome = P1[i];
P1[i] = P2[i];
P2[i] = swapChromosome;
swapIndex = P1genePosToNodeIndex;
P1genePosToNodeIndex = P2genePosToNodeIndex;
P2genePosToNodeIndex = swapIndex;
}
assert (offspring.isIndex2GenePosValid());
// create new chromosome from configuration calculated above
offsprings.add(offspring);
}
for (Chromosome c : offsprings) {
assert c.size() == GeneticPlacement.nodeProxies.length;
}
// add offsprings to the population
population.chromosomes.addAll(offsprings);
}
}
/*
* every cell is in the same location one parent or the other
*/