Adding Binary Scatter Search and the Bayesian Optimization Algorithm from the branch of Alex Seitz (rev. 926)

This commit is contained in:
Marcel Kronfeld 2011-04-27 13:02:13 +00:00
parent 0e54cf526b
commit 73efcca17b
13 changed files with 2827 additions and 0 deletions

View File

@ -0,0 +1,104 @@
package eva2.server.go.operators.crossover;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.operators.mutation.InterfaceAdaptOperatorGenerational;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
/**
* A modified version of the CrossoverEAMixer that adapts the weights with which the crossover-methods are chosen
*
* @author Alex
*
*/
public class AdaptiveCrossoverEAMixer extends CrossoverEAMixer implements InterfaceAdaptOperatorGenerational {
private Population pop = new Population();
private boolean initialized = false;
private double lastFitness = Double.MAX_VALUE;
private int[] used;
private InterfaceOptimizationProblem opt;
public AdaptiveCrossoverEAMixer(){
super();
}
public AdaptiveCrossoverEAMixer(AdaptiveCrossoverEAMixer mutator) {
super(mutator);
this.pop = (Population) mutator.pop.clone(); // TODO !Make a deep copy!?
this.initialized = mutator.initialized;
this.lastFitness = mutator.lastFitness;
this.used = mutator.used;
this.opt = mutator.opt;
}
/**
* Create a mutation mixer with equal weights of the given mutation operators.
* @param mutators
*/
public AdaptiveCrossoverEAMixer(InterfaceCrossover ... crossovers) {
this.m_Crossers = new PropertyCrossoverMixer(crossovers);
this.m_Crossers.m_SelectedTargets = m_Crossers.m_AvailableTargets.clone();
}
@Override
protected void maybeAdaptWeights(AbstractEAIndividual[] indies) {
if(initialized){
AbstractEAIndividual indy = indies[0];
this.opt.evaluate(indy);
this.pop.incrFunctionCalls();
if(indy.getFitness(0)<this.lastFitness){
this.lastFitness = indy.getFitness(0);
this.used[lastOperatorIndex] = this.used[lastOperatorIndex] + 1;
int sum = 0;
for(int i=0; i<this.used.length; i++){
sum = sum + used[i];
}
double[] weights = new double[used.length];
for(int i=0; i<weights.length; i++){
weights[i] = ((double) used[i])/sum;
}
getCrossovers().setWeights(weights);
}
}else{
System.err.println("not yet initialized");
}
}
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt, Population pop, double fit){
InterfaceCrossover[] mutators = this.m_Crossers.getSelectedCrossers();
for (int i = 0; i < mutators.length; i++) mutators[i].init(individual, opt);
this.pop = pop;
this.lastFitness = fit;
this.used = new int[getCrossovers().getWeights().length];
for(int i=0; i<this.used.length; i++){
this.used[i]=1;
}
this.opt = opt;
this.initialized = true;
}
public void update(AbstractEAIndividual individual, InterfaceOptimizationProblem opt, Population pop, double fit){
InterfaceCrossover[] mutators = this.m_Crossers.getSelectedCrossers();
for (int i = 0; i < mutators.length; i++) mutators[i].init(individual, opt);
this.pop = pop;
this.lastFitness = fit;
this.opt = opt;
}
public boolean isInitialized(){
return this.initialized;
}
public void adaptAfterSelection(Population oldPop, Population selectedPop) {
// Nothing to to here
}
public void adaptGenerational(Population oldPop, Population selectedPop,
Population newPop, boolean updateSelected) {
// TODO Perform adaption here by checking how often individuals in newPop have used which operator
// look at CrossoverEAMixer.CROSSOVER_EA_MIXER_OPERATOR_KEY or AbstractOptimizationProblem.OLD_FITNESS_KEY using AbstractEAIndividual.getData(KEY);
System.out.println("In adaptGenerational");
}
}

View File

@ -0,0 +1,78 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.server.go.strategies.BinaryScatterSearch;
import eva2.tools.math.RNG;
/**
* This crossover-Method performs a \"union\" of the selected Individuals
* It only mates 2 Individuals, not more
*
* @author Alex
*
*/
public class CM1 implements InterfaceCrossover, java.io.Serializable {
private InterfaceOptimizationProblem m_OptimizationProblem;
public CM1(){
}
public CM1(CM1 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
}
public Object clone(){
return new CM1(this);
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getIndividual(0)).getBinaryData();
for(int j=0; j<data2.size(); j++){
if(data2.get(j)){
data.set(j, true);
}
}
partners.remove(0);
for(int i=0; i<data.size(); i++){
if(RNG.flipCoin(Math.max(0, 1-BinaryScatterSearch.score(i, partners)))&&data.get(i)){
data.set(i, false);
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0]=indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return getName();
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 1";
}
public static String globalInfo() {
return "This is a Crossover Method for Binary Individuals which just forms the \"union\" of the individuals";
}
}

View File

@ -0,0 +1,78 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.server.go.strategies.BinaryScatterSearch;
import eva2.tools.math.RNG;
/**
* This crossover-Method performs an \"intersection\" of the selected Individuals
* It only mates 2 Individuals, not more
*
* @author Alex
*
*/
public class CM2 implements InterfaceCrossover, java.io.Serializable {
private InterfaceOptimizationProblem m_OptimizationProblem;
public CM2(){
}
public CM2(CM2 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
}
public Object clone(){
return new CM2(this);
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getIndividual(0)).getBinaryData();
for(int j=0; j<data2.length(); j++){
if(data2.get(j)){
data.set(j, true);
}
}
for(int i=0; i<data.size(); i++){
if(RNG.flipCoin(0.5)){
data.set(i, false);
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0]=indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return getName();
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 2";
}
public static String globalInfo() {
return "This is a Crossover Method for Binary Individuals which just forms the \"intersection\" of the individuals";
}
}

View File

@ -0,0 +1,89 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.RNG;
/**
* calculates a weight based on the fitnessValues and the configuration of each bit from the two individuals and use it as a probability to set the bit
* It only mates 2 Individuals, not more
*
* @author Alex
*
*/
public class CM3 implements InterfaceCrossover, java.io.Serializable {
private InterfaceOptimizationProblem m_OptimizationProblem;
public CM3(){
}
public CM3(CM3 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
}
public Object clone(){
return new CM3(this);
}
private int convertBoolean(boolean b){
if(b){
return 1;
}else{
return 0;
}
}
private double weight(double valX, boolean xi, double valY, boolean yi){
double result = valX*convertBoolean(xi)+valY*convertBoolean(yi);
result = result / (valX + valY);
return result;
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getEAIndividual(0)).getBinaryData();
for(int j=0; j<data.size(); j++){
double w = weight(indy1.getFitness(0), data.get(j), partners.getEAIndividual(0).getFitness(0), data2.get(j));
if(RNG.flipCoin(w)){
data.set(j, true);
}else{
data.set(j, false);
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0] = indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return this.getName();
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 3";
}
public static String globalInfo() {
return "Weight driven crossover method";
}
}

View File

@ -0,0 +1,91 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.RNG;
/**
* This crossover-Method performs an \"intersection\" of the selected Individuals and then tries to improve it through score (like in CM3)
* It only mates 2 Individuals, not more
*
* @author Alex
*
*/
public class CM4 implements InterfaceCrossover, java.io.Serializable {
private InterfaceOptimizationProblem m_OptimizationProblem;
public CM4(){
}
public CM4(CM4 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
}
public Object clone(){
return new CM4(this);
}
private int convertBoolean(boolean b){
if(b){
return 1;
}else{
return 0;
}
}
private double weight(double valX, boolean xi, double valY, boolean yi){
double result = valX*convertBoolean(xi)+valY*convertBoolean(yi);
result = result / (valX + valY);
return result;
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getEAIndividual(0)).getBinaryData();
for(int i=0; i<data.size(); i++){
boolean setBit = data.get(i);
setBit = setBit && data2.get(i);
double val = partners.getEAIndividual(0).getFitness(0);
double w = weight(indy1.getFitness(0), data.get(i), val, setBit);
data.set(i, setBit);
if(!setBit && RNG.flipCoin(w)){
data.set(i, true);
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0] = indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return this.getName();
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 4";
}
public static String globalInfo() {
return "Intersection with weight driven improvement";
}
}

View File

@ -0,0 +1,74 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.math.RNG;
/**
* This crossover-Method performs an \"intersection\" of the selected Individuals and then tries to improve it by randomly setting Bits to 1
* It only mates 2 Individuals, not more
*
* @author Alex
*
*/
public class CM5 implements InterfaceCrossover, java.io.Serializable {
private InterfaceOptimizationProblem m_OptimizationProblem;
public CM5(){
}
public CM5(CM5 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
}
public Object clone(){
return new CM5(this);
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getEAIndividual(0)).getBinaryData();
for(int i=0; i<data.size(); i++){
boolean setBit = data2.get(i);
data.set(i, setBit);
if(!setBit && RNG.flipCoin(0.5)){
data.set(i, true);
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0] = indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return this.getName();
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 5";
}
public static String globalInfo() {
return "Intersection with random change";
}
}

View File

@ -0,0 +1,80 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.server.go.strategies.BinaryScatterSearch;
import eva2.tools.math.RNG;
/**
* Score driven Crossover-Method. It uses the same score as the BinaryScatterSearch.
* Only the first individual of the given Population in the mate method is used. the rest is only for calculating the score
* It only mates 2 Individuals, not more
*
* @author Alex
*
*/
public class CM6 implements InterfaceCrossover, java.io.Serializable {
private InterfaceOptimizationProblem m_OptimizationProblem;
public CM6(){
}
public CM6(CM6 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
}
public Object clone(){
return new CM6(this);
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getIndividual(0)).getBinaryData();
for(int j=0; j<data2.size(); j++){
if(data2.get(j)){
data.set(j, true);
}
}
partners.remove(0);
for(int i=0; i<data.size(); i++){
if(!(data.get(i) && RNG.flipCoin(Math.min(0.1+BinaryScatterSearch.score(i, partners),1)))){
data.set(i, false);
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0]=indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return getName();
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 6";
}
public static String globalInfo() {
return "score driven crossover method";
}
}

View File

@ -0,0 +1,104 @@
package eva2.server.go.operators.crossover;
import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.populations.Population;
import eva2.server.go.problems.InterfaceOptimizationProblem;
/**
* This crossover-Method tries to convert the first individual into the second. If a better Individual is found on the way, this individual is chosen.
* If no better individual is found, one with the greatest distance from the both is chosen
*
* @author Alex
*
*/
public class CM7 implements InterfaceCrossover, java.io.Serializable, InterfaceEvaluatingCrossoverOperator {
private InterfaceOptimizationProblem m_OptimizationProblem;
private int evaluations = 0;
public CM7(){
}
public CM7(CM7 c){
this.m_OptimizationProblem = c.m_OptimizationProblem;
this.evaluations = c.evaluations;
}
public Object clone(){
return new CM7(this);
}
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1,
Population partners) {
AbstractEAIndividual[] result = null;
result = new AbstractEAIndividual[1];
if(partners.size()>0);
if(indy1 instanceof InterfaceDataTypeBinary && partners.getEAIndividual(0) instanceof InterfaceDataTypeBinary){
BitSet data = ((InterfaceDataTypeBinary) indy1).getBinaryData();
BitSet dataSave = (BitSet) data.clone();
BitSet data2 = ((InterfaceDataTypeBinary) partners.getEAIndividual(0)).getBinaryData();
double f1 = indy1.getFitness(0);
double f2 = partners.getEAIndividual(0).getFitness(0);
double min = Math.min(f1, f2);
int different = 0;
boolean foundBetter = false;
for(int i=0; i<data.size(); i++){
if(data.get(i) != data2.get(i)){
different++;
data.flip(i);
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
this.m_OptimizationProblem.evaluate(indy1);
this.evaluations++;
if(indy1.getFitness(0) < min){
foundBetter = true;
i=data.size();
}
}
}
if(!foundBetter){
for(int i=0; i<dataSave.size(); i++){
if(dataSave.get(i) != data2.get(i) && different > 0){
dataSave.flip(i);
}
}
}
((InterfaceDataTypeBinary) indy1).SetBinaryGenotype(data);
}
result[0] = indy1;
return result;
}
public void init(AbstractEAIndividual individual,
InterfaceOptimizationProblem opt) {
this.m_OptimizationProblem = opt;
}
public String getStringRepresentation() {
return getName();
}
public int getEvaluations(){
return this.evaluations;
}
/*****************************************************
* GUI
*/
public String getName(){
return "Combination Method 7";
}
public static String globalInfo() {
//TODO
return "";
}
public void resetEvaluations() {
this.evaluations = 0;
}
}

View File

@ -0,0 +1,13 @@
package eva2.server.go.operators.crossover;
public interface InterfaceEvaluatingCrossoverOperator extends InterfaceCrossover {
/**
* Retrieve the number of evaluations performed during crossover.
*
* @return
*/
public int getEvaluations();
public void resetEvaluations();
}

View File

@ -0,0 +1,522 @@
package eva2.server.go.strategies;
import java.util.BitSet;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import eva2.gui.BeanInspector;
import eva2.gui.GenericObjectEditor;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.GAIndividualBinaryData;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.individuals.InterfaceGAIndividual;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.populations.Population;
import eva2.server.go.populations.SolutionSet;
import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.problems.BKnapsackProblem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.Pair;
import eva2.tools.math.BayNet;
import eva2.tools.math.RNG;
/**
* Basic implementation of the Bayesian Optimization Algorithm
*
* Martin Pelikan, David E. Goldberg and Erick Cantu-Paz: 'BOA: The Bayesian Optimization Algorithm'
* the works by Martin Pelikan and David E. Goldberg.
*
* @author seitz
*
*/
public class BOA implements InterfaceOptimizer, java.io.Serializable {
private static boolean TRACE = true;
transient private InterfacePopulationChangedEventListener m_Listener = null;
private String m_Identifier = "BOA";
private int probDim = 3;
private int fitCrit = -1;
private int PopSize = 50;
private int numberOfParents = 3;
private boolean replaceNetwork = true;
private transient BayNet network = null;
private Population population = new Population();
private AbstractOptimizationProblem problem = new BKnapsackProblem();
private AbstractEAIndividual template = null;
private double learningSetRatio = 0.5;
private double resampleRatio = 0.5;
private double upperProbLimit = 0.9;
private double lowerProbLimit = 0.1;
// private networkGenerationMethod netGenMethod = networkGenerationMethod.GREEDY;
// public enum networkGenerationMethod { GREEDY, K2 };
public BOA(){
}
public BOA(int numberOfParents, int popSize, boolean replaceNetwork, double learningSetRatio, double resampleRatio){
this.numberOfParents = numberOfParents;
this.PopSize = popSize;
this.replaceNetwork = replaceNetwork;
this.learningSetRatio = learningSetRatio;
this.resampleRatio = resampleRatio;
}
public BOA(BOA b){
this.m_Listener = b.m_Listener;
this.m_Identifier = b.m_Identifier;
this.probDim = b.probDim;
this.fitCrit = b.fitCrit;
this.PopSize = b.PopSize;
this.numberOfParents = b.numberOfParents;
this.replaceNetwork = b.replaceNetwork;
this.network = (BayNet) b.network.clone();
this.population = (Population) b.population.clone();
this.problem = (AbstractOptimizationProblem) b.problem.clone();
this.template = (AbstractEAIndividual) b.template.clone();
this.learningSetRatio = b.learningSetRatio;
this.resampleRatio = b.resampleRatio;
this.upperProbLimit = b.upperProbLimit;
}
public Object clone(){
return new BOA(this);
}
public String getName() {
return "Bayesian Optimization Algorithm";
}
public static String globalInfo() {
return "Basic implementation of the Bayesian Optimization Algorithm based on the works by Martin Pelikan and David E. Goldberg.";
}
public void hideHideable() {
GenericObjectEditor.setHideProperty(this.getClass(), "population", true);
}
public void addPopulationChangedEventListener(
InterfacePopulationChangedEventListener ea) {
this.m_Listener = ea;
}
public boolean removePopulationChangedEventListener(
InterfacePopulationChangedEventListener ea) {
if (m_Listener==ea) {
m_Listener=null;
return true;
} else return false;
}
private static BitSet getBinaryData(AbstractEAIndividual indy) {
if (indy instanceof InterfaceGAIndividual) return ((InterfaceGAIndividual)indy).getBGenotype();
else if (indy instanceof InterfaceDataTypeBinary) return ((InterfaceDataTypeBinary)indy).getBinaryData();
else {
throw new RuntimeException("Unable to get binary representation for " + indy.getClass());
}
}
/**
* evaluate the given Individual and increments the counter. if the individual is null, only the counter is incremented
* @param indy the individual you want to evaluate
*/
private void evaluate(AbstractEAIndividual indy){
// evaluate the given individual if it is not null
if(indy != null){
this.problem.evaluate(indy);
}
// increment the number of evaluations
this.population.incrFunctionCalls();
}
/**
* the default initialization
*/
private void defaultInit(){
if (population==null) {
this.population = new Population(this.PopSize);
} else {
this.population.setTargetPopSize(this.PopSize);
}
this.template = this.problem.getIndividualTemplate();
if (!(template instanceof InterfaceDataTypeBinary)){
System.err.println("Requiring binary data!");
}else{
Object dim = BeanInspector.callIfAvailable(problem, "getProblemDimension", null);
if (dim==null) System.err.println("Couldnt get problem dimension!");
probDim = (Integer)dim;
((InterfaceDataTypeBinary)this.template).SetBinaryGenotype(new BitSet(probDim));
}
this.network = new BayNet(this.probDim, upperProbLimit, lowerProbLimit);
}
public void init() {
defaultInit();
this.problem.initPopulation(this.population);
this.evaluatePopulation(this.population);
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
private void evaluatePopulation(Population pop) {
for (int i=0; i<pop.size(); i++) {
evaluate(pop.getEAIndividual(i));
}
}
public void initByPopulation(Population pop, boolean reset) {
if(reset){
init();
}else{
defaultInit();
this.population = (pop);
}
}
private void generateGreedy(Population pop){
this.network = new BayNet(this.probDim, upperProbLimit, lowerProbLimit);
// BayNet net = (BayNet) this.network.clone();
// BayNet best = (BayNet) this.network.clone();
boolean improvement = true;
double score = this.network.bayesianDirichletMetric(pop);
score = 0;
// Date time = new Date();
// System.out.println("Start: "+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds());
List<Pair<Integer, Integer>> bestNetworks = new LinkedList<Pair<Integer, Integer>>();
while(improvement){
improvement = false;
// System.out.println("score:"+score);
for(int i=0; i<this.probDim; i++){
for(int j=0; j<this.probDim; j++){
if((!this.network.hasEdge(i, j)) && (i != j) && (this.network.getNode(j).getNumberOfParents() < this.numberOfParents)){
BayNet tmp = this.network;
tmp.addEdge(i, j);
if(tmp.isACyclic(i, j)){
double tmpScore = tmp.bayesianDirichletMetric(pop);
if(tmpScore >= score){
if(tmpScore == score){
bestNetworks.add(new Pair<Integer, Integer>(i, j));
}else{
bestNetworks.clear();
bestNetworks.add(new Pair<Integer, Integer>(i, j));
score = tmpScore;
improvement = true;
}
}
}
this.network.removeEdge(i, j);
}
}
}
if(bestNetworks.size() > 0){
int val = RNG.randomInt(bestNetworks.size());
Pair<Integer, Integer> pair = bestNetworks.get(val);
this.network.addEdge(pair.getHead(), pair.getTail());
}
bestNetworks.clear();
}
// time = new Date();
// System.out.println("Stop: "+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds());
}
private boolean expandGreedy(Population pop){
BayNet net = (BayNet) this.network.clone();
BayNet best = (BayNet) this.network.clone();
boolean improv = false;
boolean improvement = true;
double score = net.bayesianDirichletMetric(pop);
Date time = new Date();
// System.out.println("Start: "+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds());
while(improvement){
improvement = false;
// System.out.println("score:"+score);
for(int i=0; i<this.probDim; i++){
for(int j=0; j<this.probDim; j++){
if((!net.hasEdge(i, j)) && (i != j) && (net.getNode(j).getNumberOfParents() < this.numberOfParents)){
BayNet tmp = (BayNet) net.clone();
tmp.addEdge(i, j);
if(tmp.isACyclic()){
double tmpScore = tmp.bayesianDirichletMetric(pop);
if(tmpScore > score){
best = (BayNet) tmp.clone();
score = tmpScore;
improvement = true;
improv = true;
}
}
}
}
}
net = (BayNet) best.clone();;
}
time = new Date();
// System.out.println("Stop: "+time.getHours()+":"+time.getMinutes()+":"+time.getSeconds());
this.network = (BayNet) best.clone();
return improv;
}
/**
* Generate a Bayesian network with the individuals of the population as a reference Point
* @param pop the individuals the network is based on
*/
private void constructNetwork(Population pop){
if(this.replaceNetwork){
generateGreedy(pop);
}else{
boolean improve = expandGreedy(pop);
if(!improve){
generateGreedy(pop);
}
}
//TODO
}
/**
* generate new individuals based on the bayesian network
* @return the new individuals
*/
private Population generateNewIndys(int sampleSetSize){
Population pop = new Population(sampleSetSize);
if (TRACE) System.out.println("Resampling " + sampleSetSize + " indies...");
while(pop.size() < sampleSetSize){
AbstractEAIndividual indy = (AbstractEAIndividual) this.template.clone();
BitSet data = this.network.sample(getBinaryData(indy));
((InterfaceDataTypeBinary) indy).SetBinaryGenotype(data);
evaluate(indy);
pop.add(indy);
}
return pop;
}
/**
* Calculate a plausible number of individuals to be resampled per iteration.
* @return
*/
private int calcResampleSetSize() {
int result = (int)Math.min(PopSize, Math.max(1.0, ((double)PopSize)*resampleRatio));
// System.out.println(result);
return result;
}
/**
* Calculate a plausible number of individuals from which the BayNet is learned.
* In principle this can be independent of the resampling set size.
* @return
*/
private int calcLearningSetSize() {
return (int)Math.min(PopSize, Math.max(1.0, ((double)PopSize)*learningSetRatio));
}
public void remove(Population pop){
for(Object indy: pop){
this.population.remove(indy);
}
}
public void optimize() {
Population best = this.population.getBestNIndividuals(calcLearningSetSize(), this.fitCrit);
constructNetwork(best);
Population newlyGenerated = generateNewIndys(calcResampleSetSize());
Population toRemove = this.population.getWorstNIndividuals(calcResampleSetSize(), this.fitCrit);
remove(toRemove);
this.population.addAll(newlyGenerated);
// print();
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
/** Something has changed
*/
protected void firePropertyChangedEvent (String name) {
if (this.m_Listener != null) this.m_Listener.registerPopulationStateChanged(this, name);
}
public Population getPopulation() {
return this.population;
}
public void setPopulation(Population pop) {
this.population = pop;
}
public InterfaceSolutionSet getAllSolutions() {
return new SolutionSet(this.population);
}
public void SetIdentifier(String name) {
this.m_Identifier = name;
}
public String getIdentifier() {
return this.m_Identifier;
}
public void SetProblem(InterfaceOptimizationProblem problem) {
this.problem = (AbstractOptimizationProblem) problem;
}
public InterfaceOptimizationProblem getProblem() {
return this.problem;
}
public String getStringRepresentation() {
return "Bayesian Network";
}
public void freeWilly() {
}
//-------------------------------
//-------------GUI---------------
//-------------------------------
public int getNumberOfParents(){
return this.numberOfParents;
}
public void setNumberOfParents(int i){
this.numberOfParents = i;
}
public String numberOfParentsTipText(){
return "The maximum number of parents a node in the Bayesian Network can have";
}
public boolean getReplaceNetwork(){
return this.replaceNetwork;
}
public void setReplaceNetwork(boolean b){
this.replaceNetwork = b;
}
public String replaceNetworkTipText(){
return "if set, the network will be completely replaced. If not, it will be tried to improve the last network, if that is not possible, it will be replaced";
}
// public networkGenerationMethod getNetworkGenerationMethod(){
// return this.netGenMethod;
// }
//
// public void setNetworkGenerationMethod(networkGenerationMethod n){
// this.netGenMethod = n;
// }
//
// public String networkGenerationMethodTipText(){
// return "The Method with which the Bayesian Network will be gererated";
// }
public void print(){
this.network.print();
}
public static void main(String[] args){
Population pop = new Population();
GAIndividualBinaryData indy1 = new GAIndividualBinaryData();
indy1.setBinaryDataLength(3);
GAIndividualBinaryData indy2 = (GAIndividualBinaryData) indy1.clone();
GAIndividualBinaryData indy3 = (GAIndividualBinaryData) indy1.clone();
GAIndividualBinaryData indy4 = (GAIndividualBinaryData) indy1.clone();
GAIndividualBinaryData indy5 = (GAIndividualBinaryData) indy1.clone();
BitSet data1 = indy1.getBinaryData();
BitSet data2 = indy2.getBinaryData();
BitSet data3 = indy3.getBinaryData();
BitSet data4 = indy4.getBinaryData();
BitSet data5 = indy5.getBinaryData();
data1.set(0, true);
data1.set(1, true);
data1.set(2, false);
data2.set(0, true);
data2.set(1, true);
data2.set(2, true);
data3.set(0, false);
data3.set(1, true);
data3.set(2, false);
data4.set(0, false);
data4.set(1, true);
data4.set(2, true);
data5.set(0, true);
data5.set(1, false);
data5.set(2, false);
indy1.SetBinaryGenotype(data1);
indy2.SetBinaryGenotype(data2);
indy3.SetBinaryGenotype(data3);
indy4.SetBinaryGenotype(data4);
indy5.SetBinaryGenotype(data5);
pop.add(indy1);
pop.add(indy2);
AbstractEAIndividual ind = (AbstractEAIndividual) indy2.clone();
pop.add(ind);
// pop.add(indy3);
// pop.add(indy4);
// pop.add(indy5);
BOA b = new BOA();
b.generateGreedy(pop);
System.out.println(pop.getStringRepresentation());
b.print();
}
public int getPopulationSize() {
return PopSize;
}
public void setPopulationSize(int popSize) {
PopSize = popSize;
}
public String populationSizeTipText() {
return "Define the pool size used by BOA";
}
public double getResamplingRatio() {
return resampleRatio;
}
public void setResamplingRatio(double resampleRat) {
this.resampleRatio = resampleRat;
}
public String resamplingRatioTipText() {
return "Ratio of individuals to be resampled from the Bayesian network per iteration";
}
public double getLearningRatio() {
return learningSetRatio;
}
public void setLearningRatio(double rat) {
this.learningSetRatio = rat;
}
public String learningRatioTipText() {
return "Ratio of individuals to be used to learn the Bayesian network";
}
public double getProbLimitHigh() {
return upperProbLimit;
}
public void setProbLimitHigh(double upperProbLimit) {
this.upperProbLimit = upperProbLimit;
}
public String probLimitHighTipText(){
return "the upper limit of the probability to set one Bit to 1";
}
public double getProbLimitLow() {
return lowerProbLimit;
}
public void setProbLimitLow(double lowerProbLimit) {
this.lowerProbLimit = lowerProbLimit;
}
public String probLimitLowTipText(){
return "the lower limit of the probability to set one Bit to 1";
}
public String[] customPropertyOrder() {
return new String[] {"learningRatio", "resamplingRatio"};
}
}

View File

@ -0,0 +1,844 @@
package eva2.server.go.strategies;
import java.util.ArrayList;
import java.util.BitSet;
import eva2.gui.BeanInspector;
import eva2.server.go.InterfacePopulationChangedEventListener;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.individuals.InterfaceGAIndividual;
import eva2.server.go.operators.crossover.AdaptiveCrossoverEAMixer;
import eva2.server.go.operators.crossover.CM1;
import eva2.server.go.operators.crossover.CM2;
import eva2.server.go.operators.crossover.CM3;
import eva2.server.go.operators.crossover.CM4;
import eva2.server.go.operators.crossover.CM5;
import eva2.server.go.operators.crossover.CM6;
import eva2.server.go.operators.crossover.CM7;
import eva2.server.go.operators.distancemetric.GenotypeMetricBitSet;
import eva2.server.go.populations.InterfaceSolutionSet;
import eva2.server.go.populations.Population;
import eva2.server.go.populations.SolutionSet;
import eva2.server.go.problems.AbstractOptimizationProblem;
import eva2.server.go.problems.B1Problem;
import eva2.server.go.problems.InterfaceOptimizationProblem;
import eva2.tools.Pair;
import eva2.tools.math.RNG;
/**
* A BinaryScatterSearch implementation taken mainly from [i].
*
* @author Alex
*
* F. Gortazar, A. Duarte, M. Laguna and R. Marti: Black Box Scatter Search for General Classes of Binary Optimization Problems
* Computers and Operations research, vol. 37, no. 11, pp. 1977-1986 (2010)
*/
public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializable, InterfacePopulationChangedEventListener {
private static boolean TRACE = false;
transient private InterfacePopulationChangedEventListener m_Listener = null;
private String m_Identifier = "BinaryScatterSearch";
private int MaxImpIter = 5;
private int poolSize = 100;
private int refSetSize = 10;
private int fitCrit = -1;
private int probDim = -1;
private int generationCycle = 500;
private double th1 = 0.5;
private double th2 = 0.5;
private double g1 = 1.0/3.0;
private double g2 = 1.0/3.0;
private boolean firstTime = true;
private AbstractEAIndividual template = null;
private AbstractOptimizationProblem problem = new B1Problem();
private Population pool = new Population();
private Population refSet = new Population(10);
private AdaptiveCrossoverEAMixer cross = new AdaptiveCrossoverEAMixer(new CM1(), new CM2(), new CM3(), new CM4(), new CM5(), new CM6(), new CM7());
/**
* Create a new BinaryScatterSearch with default values
*/
public BinaryScatterSearch(){
}
/**
* Create a new BinaryScatterSearch with the same parameters as the given BinaryScatterSearch
* @param b
*/
public BinaryScatterSearch(BinaryScatterSearch b){
this.m_Listener = b.m_Listener;
this.m_Identifier = b.m_Identifier;
this.MaxImpIter = b.MaxImpIter;
this.poolSize = b.poolSize;
this.refSetSize = b.refSetSize;
this.fitCrit = b.fitCrit;
this.probDim = b.probDim;
this.generationCycle= b.generationCycle;
this.th1 = b.th1;
this.th2 = b.th2;
this.g1 = b.g1;
this.g2 = b.g2;
this.firstTime = b.firstTime;
this.template = b.template;
this.problem = b.problem;
this.pool = b.pool;
this.refSet = b.refSet;
this.cross = b.cross;
}
/**
* Create a new BinaryScatterSearch with the given Parameters
* @param refSetS the refSetSize
* @param poolS the poolSize
* @param lowerThreshold the lower Boundary for the local Search
* @param upperThreshold the upper Boundary for the local Search
* @param perCentFirstIndGenerator how many individuals (in prospect of the poolSize) are generated through the first Generator
* @param perCentSecondIndGenerator how many individuals (in prospect of the poolSize) are generated through the second Generator
* @param prob the Problem
*/
public BinaryScatterSearch(
int refSetS, int poolS, double lowerThreshold, double upperThreshold,
double perCentFirstIndGenerator, double perCentSecondIndGenerator, AbstractOptimizationProblem prob) {
this.refSetSize = refSetS;
this.poolSize= poolS;
this.th1 = lowerThreshold;
this.th2 = upperThreshold;
this.g1 = perCentFirstIndGenerator;
this.g2 = perCentSecondIndGenerator;
this.problem = prob;
}
/**
* Create a new BinaryScatterSearch with the given Parameters
* @param refSetS the refSetSize
* @param poolS the poolSize
* @param lowerThreshold the lower Boundary for the local Search
* @param upperThreshold the upper Boundary for the local Search
* @param perCentFirstIndGenerator how many individuals (in prospect of the poolSize) are generated through the first Generator
* @param perCentSecondIndGenerator how many individuals (in prospect of the poolSize) are generated through the second Generator
* @param prob the Problem
* @param cross the Crossover-Operators
*/
public BinaryScatterSearch(
int refSetS, int poolS, double lowerThreshold, double upperThreshold,
double perCentFirstIndGenerator, double perCentSecondIndGenerator,
AbstractOptimizationProblem prob, AdaptiveCrossoverEAMixer cross) {
this.refSetSize = refSetS;
this.poolSize= poolS;
this.th1 = lowerThreshold;
this.th2 = upperThreshold;
this.g1 = perCentFirstIndGenerator;
this.g2 = perCentSecondIndGenerator;
this.problem = prob;
this.cross = cross;
}
/**
* @return a copy of the current BinaryScatterSearch
*/
public Object clone(){
return new BinaryScatterSearch(this);
}
public String getName() {
return "BSS";
}
public void addPopulationChangedEventListener(
InterfacePopulationChangedEventListener ea) {
this.m_Listener = ea;
}
public boolean removePopulationChangedEventListener(
InterfacePopulationChangedEventListener ea) {
if (m_Listener==ea) {
m_Listener=null;
return true;
} else return false;
}
/**
* evaluate the given Individual and increments the counter. if the individual is null, only the counter is incremented
* @param indy the individual you want to evaluate
*/
private void evaluate(AbstractEAIndividual indy){
// evaluate the given individual if it is not null
if(indy != null){
this.problem.evaluate(indy);
}
// increment the number of evaluations
this.refSet.incrFunctionCalls();
}
/**
* Default initialization
*/
private void defaultInit(){
this.refSet = new Population();
this.template = this.problem.getIndividualTemplate();
if (!(template instanceof InterfaceDataTypeBinary)){
System.err.println("Requiring binary data!");
}else{
Object dim = BeanInspector.callIfAvailable(problem, "getProblemDimension", null);
if (dim==null) System.err.println("Couldnt get problem dimension!");
probDim = (Integer)dim;
((InterfaceDataTypeBinary)this.template).SetBinaryGenotype(new BitSet(probDim));
}
this.firstTime = true;
this.cross.init(this.template, problem, refSet, Double.MAX_VALUE);
refSet.addPopulationChangedEventListener(this);
this.refSet.setNotifyEvalInterval(this.generationCycle);
}
public void init() {
defaultInit();
initRefSet(diversify());
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
public void initByPopulation(Population pop, boolean reset) {
defaultInit();
initRefSet(diversify(pop));
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
/**
*
* @return a new diversified Population
*/
private Population diversify(){
return diversify(new Population());
}
/**
*
* @param pop the initial Population
* @return a diversified Population with all the Individuals in the initial Population
*/
private Population diversify(Population pop){
pop = generateG1(pop);
pop = generateG2(pop);
pop = generateG3(pop);
return pop;
}
/**
* generate a new Population with diverse Individuals starting with 000...000, then 010101...01, 101010...10, 001001001...001, 110110110...110 and so on
* @param pop the initial Population
* @return the new Population
*/
private Population generateG1(Population pop){
boolean method1 = true;
int i=1;
while(pop.size() < ((double) this.poolSize) * this.g1){
AbstractEAIndividual indy = (AbstractEAIndividual) this.template.clone();
BitSet data = getBinaryData(indy);
if(method1){
method1 = !method1;
data.set(0, data.size(), true);
for(int j=0; j<data.size(); j=j+i){
data.flip(j);
}
((InterfaceDataTypeBinary) indy).SetBinaryGenotype(data);
if(i==1){
i++;
method1 = !method1;
}
}else{
method1 = !method1;
if(i!=1){
data.set(0, data.size(), false);
for(int j=0; j<data.size(); j=j+i){
data.flip(j);
}
((InterfaceDataTypeBinary) indy).SetBinaryGenotype(data);
}
i++;
}
pop.add(indy);
evaluate((AbstractEAIndividual) indy);
}
return pop;
}
/**
* Generate new Individuals that have the individuals of the given Population as a base
* @param pop the population
* @return the new Population
*/
private Population generateG2(Population pop){
while(pop.size() < ((double) this.poolSize) * (this.g1 + this.g2)){
AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
InterfaceDataTypeBinary dblIndy = (InterfaceDataTypeBinary) indy;
BitSet data = dblIndy.getBinaryData();
data.set(0, data.size(), false);
for(int i=0; i<data.size(); i++){
if(RNG.flipCoin(Math.min(0.1+score(i, pop),1))){
data.set(i, true);
}
}
dblIndy.SetBinaryGenotype(data);
if(!contains(dblIndy, pop)){
pop.add(dblIndy);
evaluate(indy);
}
}
return pop;
}
/**
* Generate new Individuals that have the individuals of the given Population as a base
* @param pop the population
* @return the new Population
*/
private Population generateG3(Population pop){
while(pop.size() <= this.poolSize){
AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
InterfaceDataTypeBinary dblIndy = (InterfaceDataTypeBinary)indy;
BitSet data = dblIndy.getBinaryData();
data.set(0, data.size(), true);
for(int i=0; i<data.size(); i++){
if(RNG.flipCoin(Math.max(0, 1-score(i, pop)))){//???
data.set(i, false);
}
}
dblIndy.SetBinaryGenotype(data);
if(!contains(dblIndy, pop)){
pop.add(dblIndy);
evaluate(indy);
}
}
return pop;
}
/**
* calculate the number of individuals in the given Population that have a 1 at the i-th position
* @param i the position
* @param pop the population
* @return The number of individuals that have a '1' on the i-th position
*/
private static double calculateNumberOFPI1(int i, Population pop){
int result = 0;
for(int j=0; j<pop.size(); j++){
AbstractEAIndividual indy = pop.getEAIndividual(j);
BitSet binData = getBinaryData(indy);
if(binData.get(i)){
result++;
}
}
return result;
}
/**
* calculate the number of individuals in the given Population that have a 0 at the i-th position
* @param i the position
* @param pop the population
* @return The number of individuals that have a '0' on the i-th position
*/
private static double calculateNumberOFPI0(int i, Population pop){
int result = 0;
for(int j=0; j<pop.size(); j++){
AbstractEAIndividual indy = pop.getEAIndividual(j);
BitSet binData = getBinaryData(indy);
if(!binData.get(i)){
result++;
}
}
return result;
}
private static BitSet getBinaryData(AbstractEAIndividual indy) {
if (indy instanceof InterfaceGAIndividual) return ((InterfaceGAIndividual)indy).getBGenotype();
else if (indy instanceof InterfaceDataTypeBinary) return ((InterfaceDataTypeBinary)indy).getBinaryData();
else {
throw new RuntimeException("Unable to get binary representation for " + indy.getClass());
}
}
/**
* calculate the sum of all the FitnessValues of the individuals that have a '0' at the i-th position
* @param i the position
* @param pop the population
* @return the sum
*/
private static double calculateSumPI0(int i, Population pop){
double result = 0;
for(int j=0; j<pop.size(); j++){
AbstractEAIndividual indy = pop.getEAIndividual(j);
BitSet binData = getBinaryData(indy);
if(binData.get(i)){
result += indy.getFitness(0);
}
}
return result;
}
/**
* calculate the sum of all the FitnessValues of the individuals that have a '0' at the i-th position
* @param i the position
* @param pop the population
* @return the sum
*/
private static double calculateSumPI1(int i, Population pop){
double result = 0;
for(int j=0; j<pop.size(); j++){
AbstractEAIndividual indy = pop.getEAIndividual(j);
BitSet binData = getBinaryData(indy);
if(binData.get(i)){
result += indy.getFitness(0);
}
}
return result;
}
/**
* calculates a score that gives a reference Point if the Bit on the i-th position is right.
* If the bit is set to '1' and you get a high score then the Bit is probably set correct.
* If the bit is set to '0' and you get a low score then the Bit is probably set correct.
* @param i the position
* @param pop the population
* @return the score
*/
public static double score(int i, Population pop){
double sumPI1 = calculateSumPI1(i, pop);
double sumPI0 = calculateSumPI0(i, pop);
double numberOfPI1 = calculateNumberOFPI1(i, pop);
double numberOfPI0 = calculateNumberOFPI0(i, pop);
double v= (sumPI1/numberOfPI1)/((sumPI1/numberOfPI1)+(sumPI0/numberOfPI0));
return v;
}
/**
* calculate the first RefSet with the given Population as a reference Point
* @param pop the generated Pool
*/
private void initRefSet(Population pop){
this.problem.evaluatePopulationStart(this.refSet);
this.pool = pop;
refSetUpdate(true);
Population best = this.refSet.getBestNIndividuals(this.refSetSize/2, fitCrit);
for(int i=0; i<best.size(); i++){
//improve(best.getEAIndividual(i));
AbstractEAIndividual indy = best.getEAIndividual(i);
AbstractEAIndividual x = improve((AbstractEAIndividual)indy.clone());
if(x.getFitness(0)<indy.getFitness(0) && !contains((InterfaceDataTypeBinary)x, this.refSet)){
this.refSet.remove(indy);
this.refSet.add(x);
}
}
this.problem.evaluatePopulationEnd(this.refSet);
}
/**
* Update the reference Set
* @param replaceWorstHalf replaces the worst half of the RefSet if set
* @return has the Population changed
*/
private boolean refSetUpdate(boolean replaceWorstHalf){
boolean refSetChanged = false;
Population rest = (Population) this.pool.clone();
if(this.firstTime){
Population tmp = this.pool.getBestNIndividuals(this.pool.size(), this.fitCrit);
int i=0;
while(this.refSet.size() < this.refSetSize){
this.refSet.add(tmp.get(i));
i++;
}
rest = this.pool.getWorstNIndividuals(this.poolSize-i, this.fitCrit);
refSetChanged = true;
}
if(replaceWorstHalf){
refSetChanged = true;
// delete the worst half of refSet
this.refSet.removeMembers(this.refSet.getWorstNIndividuals(this.refSet.size()-this.refSetSize/2, this.fitCrit), false);
while(this.refSet.size()<this.refSetSize){
ArrayList<Pair<Integer,Double>> list = new ArrayList<Pair<Integer,Double>>();
for(int i=0; i< this.refSet.size(); i++){
AbstractEAIndividual indy = this.refSet.getEAIndividual(i);
list.add(Population.getClosestFarthestIndy(indy, rest, new GenotypeMetricBitSet(), false));
}
Pair<Integer,Double> pair = list.get(0);
for(Pair<Integer,Double> p: list){
if(p.getTail()<pair.getTail()){
pair=p;
}
}
this.refSet.add(rest.getEAIndividual(pair.getHead()));
rest.remove(pair.getHead());
}
}else{
Population best = this.pool.getBestNIndividuals(this.refSetSize, this.fitCrit);
while(best.size()>0 && best.getBestEAIndividual().getFitness(0)<this.refSet.getWorstEAIndividual().getFitness(0)){
if(!contains((InterfaceDataTypeBinary)best.getBestIndividual(), this.refSet)){
refSetChanged = true;
this.refSet.remove(this.refSet.getWorstEAIndividual());
this.refSet.add(best.getBestIndividual());
}
best.remove(best.getBestEAIndividual());
}
}
this.firstTime = false;
return refSetChanged;
}
/**
* Order the given List according to the score of the given values
* @param list the initial List
* @return the ordered List
*/
private ArrayList<Integer> order(ArrayList<Integer> list){
ArrayList<Integer> result = new ArrayList<Integer>();
for(Integer s: list){
boolean done = false;
if(result.isEmpty()){
result.add(s);
}else{
for(int i=0; i<result.size(); i++){
if(score(s, this.refSet)>score(result.get(i), this.refSet)&&!done){
result.add(i,s);
done = true;
}
}
if(!done){
result.add(s);
}
}
}
return result;
}
/**
* Do a local search
* @param indy the individual that will be improved
* @return the new improved individual
*/
private AbstractEAIndividual improve(AbstractEAIndividual indy){
AbstractEAIndividual tmpIndy = (AbstractEAIndividual) indy.clone();
BitSet data = ((InterfaceDataTypeBinary)tmpIndy).getBinaryData();
ArrayList<Integer> cl = new ArrayList<Integer>();
int localIter = 0;
for(int i=0; i<data.size(); i++){
if(data.get(i)){
if(score(i, this.refSet)<=this.th2){
cl.add(i);
}
}else{
if(score(i, this.refSet)>=this.th1){
cl.add(i);
}
}
}
cl = order(cl);
boolean improvement = true;
while(improvement && localIter < this.MaxImpIter){
improvement = false;
for(int i:cl){
data.flip(i);
((InterfaceDataTypeBinary) tmpIndy).SetBinaryGenotype(data);
evaluate(tmpIndy);
if(tmpIndy.getFitness(0)<indy.getFitness(0)){
improvement = true;
indy = (AbstractEAIndividual) tmpIndy.clone();
data = ((InterfaceDataTypeBinary)tmpIndy).getBinaryData();
}else{
tmpIndy = (AbstractEAIndividual) indy.clone();
}
}
cl = order(cl);
for(int i=0; i<cl.size()-1; i++){
boolean valI = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData().get(i);
for(int j=i+1; j<cl.size(); j++){
boolean valJ = ((InterfaceDataTypeBinary) tmpIndy).getBinaryData().get(i);
if(valJ != valI){
data.set(i, valJ);
data.set(j, valI);
((InterfaceDataTypeBinary) tmpIndy).SetBinaryGenotype(data);
evaluate(tmpIndy);
if(tmpIndy.getFitness(0)<indy.getFitness(0)){
improvement = true;
indy = (AbstractEAIndividual) tmpIndy.clone();
data = ((InterfaceDataTypeBinary)tmpIndy).getBinaryData();
i=cl.size();
j=cl.size();
}else{
tmpIndy = (AbstractEAIndividual) indy.clone();
}
}
}
}
localIter++;
}
return indy;
}
/**
* Combine all the individuals in the reference Set (always 2)
* @return the List with all the combinations
*/
public ArrayList<Population> generateSubsets(){
ArrayList<Population> result = new ArrayList<Population>();
for(int i=0; i<this.refSet.size(); i++){
for(int j=i+1; j<this.refSet.size(); j++){
Population tmp = new Population();
tmp.add(this.refSet.getIndividual(i));
tmp.add(this.refSet.getIndividual(j));
result.add((Population) tmp.clone());
}
}
return result;
}
/**
* combine the first individual with the second one
* @param pop the Population
* @return the new Individual
*/
public AbstractEAIndividual combineSolution(Population pop){
AbstractEAIndividual result = (AbstractEAIndividual) template.clone();
if(pop.size()>=2){
AbstractEAIndividual indy1 = pop.getEAIndividual(0);
pop.remove(0);
// Because some Crossover-Methods need the score, we need to give them the RefSet
for(int i=0; i<this.refSet.size(); i++){
pop.add(this.refSet.getEAIndividual(i));
}
this.cross.update(indy1, problem, refSet, indy1.getFitness(0));
result = this.cross.mate(indy1, pop)[0];
evaluate(null);
//result = indy1.mateWith(s)[0];
}else if(pop.size()>0){
result = pop.getBestEAIndividual();
}else{
System.err.println("Population empty");
//return null;
}
return result;
}
/**
* look if the individual is already in the population
* @param indy the Individual to be tested
* @param pop the population in where to search
* @return is the individual already in the Population
*/
private boolean contains(InterfaceDataTypeBinary indy, Population pop){
if(pop.size()<=0){
return false;
}else{
BitSet data = indy.getBinaryData();
for(int i=0; i<pop.size(); i++){
BitSet tmpData = ((InterfaceDataTypeBinary) pop.getEAIndividual(i)).getBinaryData();
if(tmpData.equals(data)){
return true;
}
}
return false;
}
}
public void optimize() {
problem.evaluatePopulationStart(refSet);
int funCallsStart = this.refSet.getFunctionCalls();
do {
// generate a new Pool
this.pool = new Population();
ArrayList<Population> newSubsets = generateSubsets();
for(int i=0; i<newSubsets.size(); i++){
Population s = newSubsets.get(i);
AbstractEAIndividual x = combineSolution(s);
if(!contains((InterfaceDataTypeBinary)x,this.pool)&&this.pool.size()<=this.poolSize){
this.pool.add(x);
}
}
this.refSet.incrFunctionCallsBy(this.pool.size());
// increase the number of evaluations by the number of evaluations that are performed in the crossover-step
for(int i=0; i<this.cross.getEvaluations(); i++){
evaluate(null);
}
// reset the extra evaluations
this.cross.resetEvaluations();
// get the best half of the Populations
Population best = this.refSet.getBestNIndividuals(this.refSetSize/2, fitCrit);
// do a local search on the better half of the reference Set
for(int i=0; i<best.size(); i++){
AbstractEAIndividual indy = best.getEAIndividual(i);
AbstractEAIndividual x = improve((AbstractEAIndividual)indy.clone());
if(x.getFitness(0)<indy.getFitness(0) && !contains((InterfaceDataTypeBinary)x, this.refSet)){
this.refSet.remove(indy);
this.refSet.add(x);
}
}
// update the referenceSet
boolean changed = refSetUpdate(false);
// if no change occurred, replace the worst half of the referenceSet
if(!changed){
refSetUpdate(true);
}
} while (refSet.getFunctionCalls()-funCallsStart < generationCycle);
problem.evaluatePopulationEnd(refSet);
}
public Population getPopulation() {
return this.refSet;
}
public void setPopulation(Population pop) {
this.refSet = pop;
this.refSetSize = pop.getTargetSize();
}
public String populationTipText(){
return "The Population";
}
public InterfaceSolutionSet getAllSolutions() {
return new SolutionSet(this.refSet);
}
public void SetIdentifier(String name) {
this.m_Identifier = name;
}
public String getIdentifier() {
return this.m_Identifier;
}
public void SetProblem(InterfaceOptimizationProblem problem) {
this.problem = (AbstractOptimizationProblem) problem;
}
public InterfaceOptimizationProblem getProblem() {
return this.problem;
}
public String getStringRepresentation() {
return "BinaryScatterSearch";
}
public void freeWilly() {
// TODO Auto-generated method stub
}
protected void firePropertyChangedEvent (String name) {
if (this.m_Listener != null) this.m_Listener.registerPopulationStateChanged(this, name);
}
public void registerPopulationStateChanged(Object source, String name) {
// The events of the interim hill climbing population will be caught here
if (name.compareTo(Population.funCallIntervalReached) == 0) {
// set funcalls to real value
refSet.SetFunctionCalls(((Population)source).getFunctionCalls());
// System.out.println("FunCallIntervalReached at " + (((Population)source).getFunctionCalls()));
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
}
}
//----------GUI----------
public int getPoolSize(){
return this.poolSize;
}
public void setPoolSize(int i){
this.poolSize = i;
}
public String poolSizeTipText(){
return "The number of individuals created in the diversification step";
}
public double getThresholdHigh(){
return th2;
}
public void setThresholdHigh(double t){
this.th2 = t;
}
public String thresholdHighTipText(){
return "Only scores set to 0 with a value below this value will be improved";
}
public double getThresholdLow(){
return th1;
}
public void setThresholdLow(double t){
this.th1 = t;
}
public String thresholdLowTipText(){
return "Only scores set to 1 with a value above this value will be improved";
}
public int getLocalSearchSteps(){
return this.MaxImpIter;
}
public void setLocalSearchSteps(int i){
this.MaxImpIter = i;
}
public String localSearchStepsTipText(){
return "Maximum number of local search iterations";
}
public AdaptiveCrossoverEAMixer getCrossoverMethods(){
return this.cross;
}
public void setCrossoverMethods(AdaptiveCrossoverEAMixer c){
this.cross = c;
}
public String crossoverMethodsTipText(){
return "The crossover Methods used to create the pool";
}
public int getGenerationCycle(){
return this.generationCycle;
}
public void setGenerationCycle(int i){
this.generationCycle = i;
}
public String generationCycleTipText(){
return "The number of evaluations done in every generation Cycle";
}
public double getPerCentFirstGenMethod(){
return this.g1;
}
public void setPerCentFirstGenMethod(double d){
this.g1 = d;
}
public String perCentFirstGenMethodTipText(){
return "The number of individuals generated with the first Generation Method. The percentage, that is not covered with the first and the second method will be covered with a third method";
}
public double getPerCentSecondGenMethod(){
return this.g2;
}
public void setPerCentSecondGenMethod(double d){
this.g2 = d;
}
public String perCentSecondGenMethodTipText(){
return "The number of individuals generated with the second Generation Method. The percentage, that is not covered with the first and the second method will be covered with a third method";
}
public static String globalInfo(){
return "A basic implementation of a Binary ScatterSearch";
}
}

View File

@ -0,0 +1,639 @@
package eva2.tools.math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.LinkedList;
import java.util.List;
import eva2.gui.BeanInspector;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.GAIndividualBinaryData;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
import eva2.server.go.individuals.InterfaceGAIndividual;
import eva2.server.go.populations.Population;
import eva2.tools.Pair;
public class BayNet {
private boolean[][] network = null;
private int dimension = 5;
private BayNode[] nodes = null;
private List<BayNode> rootNodes = new LinkedList<BayNode>();
private double upperProbLimit = 0.9;
private double lowerProbLimit = 0.1;
public BayNet(int dimension, double upperLimit, double lowerLimit){
this.dimension = dimension;
this.upperProbLimit = upperLimit;
this.lowerProbLimit = lowerLimit;
init();
}
public BayNet(BayNet b){
this.network = cloneNetwork(b.network);
this.dimension = b.dimension;
this.nodes = new BayNode[b.dimension];
for(int i=0; i<this.nodes.length; i++){
this.nodes[i] = (BayNode) b.nodes[i].clone();
}
this.rootNodes = new LinkedList<BayNode>();
for(BayNode node: b.rootNodes){
this.rootNodes.add(this.nodes[node.getId()]);
}
this.upperProbLimit = b.upperProbLimit;
this.lowerProbLimit = b.lowerProbLimit;
}
public Object clone(){
return new BayNet(this);
}
private boolean[][] cloneNetwork(boolean[][] b){
boolean[][] result = new boolean[b.length][b.length];
for(int i=0; i<b.length; i++){
for(int j=0; j<b.length; j++){
if(b[i][j]){
result[i][j] = true;
}
}
}
return result;
}
/**
* initialize the Network
*/
public void init(){
this.network = new boolean[this.dimension][this.dimension];
this.nodes = new BayNode[this.dimension];
for(int i=0; i<this.dimension; i++){
this.nodes[i] = new BayNode(i);
this.rootNodes.add(this.nodes[i]);
}
}
private static BitSet getBinaryData(AbstractEAIndividual indy) {
if (indy instanceof InterfaceGAIndividual) return ((InterfaceGAIndividual)indy).getBGenotype();
else if (indy instanceof InterfaceDataTypeBinary) return ((InterfaceDataTypeBinary)indy).getBinaryData();
else {
throw new RuntimeException("Unable to get binary representation for " + indy.getClass());
}
}
/**
*
* @return a list of the root nodes
*/
public List<BayNode> getRootNodes(){
// ArrayList<BayNode> result = new ArrayList<BayNode>();
// for (int i=0; i<this.dimension; i++){
// // when the column is empty, we have no incoming edges and the node is a root-node
// boolean root = true;
// for(int j=0; j<this.dimension; j++){
// if(this.network[j][i]){
// root = false;
// j=this.dimension;
// }
// }
// if(root){
// result.add(getNode(i));
// }
// }
// return result;
return this.rootNodes;
}
/**
* get the i-th node
* @param i the node to be returned
* @return the requested node
*/
public BayNode getNode(int i){
return this.nodes[i];
}
/**
* return the children for a given node
* @param n the node
* @return the children of the node
*/
public List<BayNode> getChildren(BayNode n){
// ArrayList<BayNode> result = new ArrayList<BayNode>();
// int i = n.getId();
// for(int j=0; j<this.dimension; j++){
// if(this.network[i][j]){
// result.add(this.nodes[j]);
// }
// }
// return result;
List<Integer> ids = n.getChildren();
List<BayNode> result = new ArrayList<BayNode>();
for(int i: ids){
result.add(this.nodes[i]);
}
return result;
}
/**
* return the parents for a given node
* @param n the node
* @return the parents of the node
*/
public List<BayNode> getParents(BayNode n){
// ArrayList<BayNode> result = new ArrayList<BayNode>();
// int i = n.getId();
// for(int j=0; j<this.dimension; j++){
// if(this.network[j][i]){
// result.add(this.nodes[j]);
// }
// }
// if (result.size()!=n.getNumberOfParents()) {
// System.err.println("Error in getParents!");
// }
// return result;
List<Integer> ids = n.getParents();
List<BayNode> result = new LinkedList<BayNode>();
for(int i: ids){
result.add(this.nodes[i]);
}
return result;
}
/**
* return the children of a list of nodes
* @param n the list of nodes
* @return the children of the nodes
*/
public List<BayNode> getChildren(List<BayNode> n){
ArrayList<BayNode> result = new ArrayList<BayNode>();
for(BayNode node: n){
List<BayNode> children = getChildren(node);
for(BayNode nod: children){
if(!result.contains(nod)){
result.add(nod);
}
}
}
return result;
}
/**
* remove the edge from node i to node j
* @param i the node from which the edge comes
* @param j the node to which the edge points
*/
public void removeEdge(int i, int j){
if(this.network[i][j]){
this.network[i][j] = false;
this.nodes[j].decrNumberOfParents();
this.nodes[i].removeChild(j);
this.nodes[j].removeParent(i);
this.nodes[j].generateNewPTable();
if(this.nodes[j].getNumberOfParents() == 0){
this.rootNodes.add(nodes[j]);
}
}
}
/**
* add an edge from the node i to the node j
* @param i edge from this node
* @param j edge to this node
*/
public void addEdge(int i, int j){
if(!this.network[i][j]){
this.network[i][j] = true;
this.nodes[j].incrNumberOfParents();
this.nodes[j].generateNewPTable();
this.rootNodes.remove(this.nodes[j]);
this.nodes[i].addChild(j);
this.nodes[j].addParent(i);
}
}
/**
* find the next value where all the parents are already set
* @param data
* @return
*/
private int findNext(double[] probabilities, List<BayNode> nodes){
for(BayNode node: nodes){
List<BayNode> parents = getParents(node);
boolean possible = false;
for(BayNode p: parents){
if(probabilities[p.getId()] != -1){
possible = true;
}else{
possible = false;
break;
}
}
if(possible){
return node.getId();
}
}
return -1;
}
/**
* calculate a new BitSet according to the network
* @param data the BitSet that will be calculated
* @return the new BitSet
*/
public BitSet sample(BitSet data){
// generate a new probabilities-vector
double[] probabilities = new double[this.network.length];
for(int i=0; i<probabilities.length; i++){
probabilities[i] = -1;
}
// get the root-nodes (the non dependent nodes)
List<BayNode> nodes = getRootNodes();
// calculate the BitSet-Value for these nodes
for(BayNode node: nodes){
int id = node.getId();
probabilities[id] = node.getProbability(0);
data.set(id, RNG.flipCoin(probabilities[id]));
}
// find the next node that can be evaluated
List<BayNode> toCalculate = getChildren(nodes);
int next = findNext(probabilities, toCalculate);
while(next != -1){
toCalculate.remove(this.nodes[next]);
probabilities[next] = calculateNextProbability(data, toCalculate, next);
data.set(next, RNG.flipCoin(probabilities[next]));
next = findNext(probabilities, toCalculate);
}
return data;
}
/**
* calculate the next probability
* @param data the already calculated data
* @param probabilities the already calculated probabilities
* @param toCalculate the Nodes that have yet to be calculated
* @param next the node for which to calculate the probability
* @return the new probabilities array
*/
private double calculateNextProbability(BitSet data, List<BayNode> toCalculate, int next) {
toCalculate.addAll(getChildren(this.nodes[next]));
int[] parId = calculateSortedParentIds(next);
int prob = 0;
int cnt = 0;
for(int j=parId.length-1; j>=0; j--){
if(data.get(parId[j])){
prob += (int) Math.pow(2, j);
}
cnt++;
}
return this.nodes[next].getProbability(prob);
}
/**
* generate an array of the parents, sorted by there id
* @param id the id of the node
* @return the sorted parent-ids
*/
private int[] calculateSortedParentIds(int id) {
List<BayNode> parents = getParents(this.nodes[id]);
int[] parId = new int[parents.size()];
int i=0;
for(BayNode nod: parents){
parId[i] = nod.getId();
i++;
}
Arrays.sort(parId);
return parId;
}
/**
* generate an array of the parents plus the given node, sorted by there id
* @param id the id of the node
* @return the sorted parent-ids
*/
private int[] calculateSortedParentPlusNodeIds(int id) {
List<BayNode> nodes = getParents(this.nodes[id]);
nodes.add(this.nodes[id]);
int[] sortedIds = new int[nodes.size()];
int i=0;
for(BayNode nod: nodes){
sortedIds[i] = nod.getId();
i++;
}
Arrays.sort(sortedIds);
return sortedIds;
}
private void resetCalculated(){
for(int i=0; i<this.dimension; i++){
this.nodes[i].setCalculated(false);
}
}
/**
* see if the network is still acyclic after inserting the edge
* @param from the node from which the edge comes from
* @param to the node to which the edgte points
* @return is the network still acyclic
*/
public boolean isACyclic(int from, int to){
int cnt1 = 0;
int cnt2 = 0;
for(int i=0; i<this.dimension; i++){
if(this.network[i][from]){
cnt1++;
}
if(this.network[to][i]){
cnt2++;
}
}
// if the from node has no incoming edges or the to node has no outgoing edges the network is still acyclic
if(cnt1==0 || cnt2==0){
return true;
}
// look at all the children and see if we can get to the from-node from the to-node
List<BayNode> toCalculate = getChildren(this.nodes[to]);
while(!toCalculate.isEmpty()){
BayNode node = toCalculate.get(0);
toCalculate.remove(node);
if(!node.getCalculated()){
node.setCalculated(true);
if(from == node.getId()){
resetCalculated();
return false;
}
List<BayNode> children = getChildren(node);
toCalculate.addAll(children);
}
}
resetCalculated();
return true;
}
/**
* check if the given Network is acyclic
* @param net the Network
* @return is the net acyclic
*/
public boolean isACyclic(){
List<Pair<Integer,Integer>> deletedEdges = new LinkedList<Pair<Integer,Integer>>();
List<BayNode> nodes = getRootNodes();
boolean res=false;
for(int i=0; i<=this.dimension; i++){
for(BayNode node: nodes){
int id = node.getId();
for(int j=0; j<this.dimension; j++){
if (this.network[id][j]) {
this.network[id][j] = false;
deletedEdges.add(new Pair<Integer,Integer>(id,j));
}
}
}
nodes = getRootNodes();
// if we only have root nodes, we have an acyclic graph
if(nodes.size() == this.nodes.length){
res = true;
break;
}
}
// System.out.println("Deleted edges: " + BeanInspector.toString(deletedEdges));
for (Pair<Integer,Integer> edge : deletedEdges) {
this.network[edge.head][edge.tail] = true;
}
return res;
}
private double getPrior(List<BayNode> parents, Population pop){
return (double) pop.size() / Math.pow(2.0, (double) parents.size());
}
private double getPrior(List<BayNode> parents, BayNode current, Population pop){
return getPrior(parents, pop) / 2.0;
}
private void setRootPTables(Population pop){
List<BayNode> rootNodes = getRootNodes();
for(BayNode node: rootNodes){
int id = node.getId();
double count = 0;
for(int i=0; i<pop.size(); i++){
BitSet data = getBinaryData(pop.getEAIndividual(i));
if(data.get(id)){
count++;
}
}
double prob = count / (double) pop.size();
setProbability(node, 0, prob);
// node.setPTable(0, count / (double) pop.size());
}
}
public void setUpperProbLimit(double upperProbLimit) {
this.upperProbLimit = upperProbLimit;
}
public void setLowerProbLimit(double lowerProbLimit) {
this.lowerProbLimit = lowerProbLimit;
}
/**
* calculate the bayesian Dirichlet Metric
* @param pop the population on which the metric is based on
* @return the metric
*/
public double bayesianDirichletMetric(Population pop){
double result = 1.0;
//for every node
setRootPTables(pop);
for(int i=0; i<this.dimension; i++){
BayNode currentNode = this.nodes[i];
//get the parents
List<BayNode> parents = getParents(currentNode);
// System.out.println("parents: "+parents.size());
// get the parentIds sorted (for the lookup)
if(!parents.isEmpty()){
int[] parId = calculateSortedParentIds(i);
// the parentIds plus the id of the current node sorted (for the lookup
int[] nodeIds = calculateSortedParentPlusNodeIds(i);
double[] pTable = currentNode.getPTable();
for(int j=0; j<pTable.length; j++){
Population pop2 = numberSetCorrectly(pop, j, parId);
double count = (double) pop2.size();
double numeratorFirstFraction = SpecialFunction.gamma(getPrior(parents, pop));
double denominatorFirstFraction = SpecialFunction.gamma(getPrior(parents, pop)+count);
double firstFraction = numeratorFirstFraction / denominatorFirstFraction;
result = result * firstFraction;
// currentNode.setPTable(j, count / (double) pop.size());
count = 0;
for(int k=0; k<2; k++){
double cnt = numberSetCorrectly(pop2, j, k, nodeIds, parId);
double numeratorSecondFraction = SpecialFunction.gamma(getPrior(parents, currentNode, pop) + cnt);
double denumeratorSecondFraction = SpecialFunction.gamma(getPrior(parents, currentNode, pop));
double secondFraction = numeratorSecondFraction / denumeratorSecondFraction;
result = result * secondFraction;
double prob = cnt / (double) pop2.size();
setProbability(currentNode, j, prob);
cnt = 0;
}
}
}
}
return result;
}
private void setProbability(BayNode n, int j, double prob){
n.setPTable(j, Math.min(upperProbLimit, Math.max(lowerProbLimit, prob)));
}
private double numberSetCorrectly(Population pop, int j, int k, int[] Ids, int[] parIds){
double result = 0.0;
String binaryString = Integer.toBinaryString(j);
while(binaryString.length() < parIds.length){
binaryString = "0"+binaryString;
}
boolean found = false;
boolean end = false;
int different = 0;
for(int i=0; i<parIds.length; i++){
if(parIds[i] != Ids[i]){
different = i;
found = true;
break;
}
}
if(!found){
different = Ids.length;
end = true;
}
if(end){
binaryString = binaryString+k;
}else{
binaryString = binaryString.substring(0, different)+k+binaryString.substring(different);
}
int l = Integer.parseInt(binaryString);
// binary = getBinaryArray(Ids, binaryString);
for(int i=0; i<pop.size(); i++){
AbstractEAIndividual indy = pop.getEAIndividual(i);
BitSet data = ((InterfaceDataTypeBinary) indy).getBinaryData();
boolean setCorrectly = isSetCorrectly(Ids, data, l);
if(setCorrectly){
result ++;
}
}
return result;
}
private Population numberSetCorrectly(Population pop, int j, int[] Ids){
Population result = new Population();
// String binaryString = Integer.toBinaryString(j);
// append zeroes to the front
// boolean[] binary = getBinaryArray(Ids, binaryString);
for(int i=0; i<pop.size(); i++){
AbstractEAIndividual indy = pop.getEAIndividual(i);
BitSet data = ((InterfaceDataTypeBinary) indy).getBinaryData();
boolean setCorrectly = isSetCorrectly(Ids, data, j);
if(setCorrectly){
// result ++;
result.add(indy);
}
}
return result;
}
/**
* is the BitSet of the individual set correctly corresponding to the binary String and the parId
* @param ids the Ids of the parents sorted
* @param data the data of the individual to be checked
* @param j how the Bits have to be set (as Integer)
* @return is the data set correctly
*/
private boolean isSetCorrectly(int[] ids, BitSet data, int j) {
boolean setCorrectly = false;
for(int m=0; m<ids.length; m++){
if(((j & (1<<m))>0) && (data.get(ids[m]))){
setCorrectly = true;
}else if(!((j & (1<<m))>0) && (!data.get(ids[m]))){
setCorrectly = true;
}else{
setCorrectly = false;
m = j+10;
}
}
return setCorrectly;
}
public void print(){
for(int i=0; i<this.dimension; i++){
for(int j=0; j<this.dimension; j++){
if(this.network[i][j]){
System.out.print("1");
}else{
System.out.print("0");
}
}
System.out.println();
}
for(int i=0; i<this.dimension; i++){
System.out.println(BeanInspector.toString(nodes[i].getPTable()));
}
}
/**
* has the network already an edge from node i to node j
* @param i the node from which the edge originates
* @param j the node to which the edge points
* @return is the edge already there
*/
public boolean hasEdge(int i, int j){
return this.network[i][j];
}
public static void main(String[] args){
BayNet b = new BayNet(3, 0.9, 0.1);
b.addEdge(0, 2);
b.addEdge(1, 2);
Population pop = new Population();
GAIndividualBinaryData indy1 = new GAIndividualBinaryData();
indy1.setBinaryDataLength(3);
GAIndividualBinaryData indy2 = (GAIndividualBinaryData) indy1.clone();
GAIndividualBinaryData indy3 = (GAIndividualBinaryData) indy1.clone();
GAIndividualBinaryData indy4 = (GAIndividualBinaryData) indy1.clone();
GAIndividualBinaryData indy5 = (GAIndividualBinaryData) indy1.clone();
BitSet data1 = indy1.getBinaryData();
BitSet data2 = indy2.getBinaryData();
BitSet data3 = indy3.getBinaryData();
BitSet data4 = indy4.getBinaryData();
BitSet data5 = indy5.getBinaryData();
data1.set(0, true);
data1.set(1, true);
data1.set(2, false);
data2.set(0, true);
data2.set(1, true);
data2.set(2, true);
data3.set(0, false);
data3.set(1, true);
data3.set(2, false);
data4.set(0, false);
data4.set(1, true);
data4.set(2, true);
data5.set(0, true);
data5.set(1, false);
data5.set(2, false);
indy1.SetBinaryGenotype(data1);
indy2.SetBinaryGenotype(data2);
indy3.SetBinaryGenotype(data3);
indy4.SetBinaryGenotype(data4);
indy5.SetBinaryGenotype(data5);
pop.add(indy1);
pop.add(indy2);
pop.add(indy3);
pop.add(indy4);
pop.add(indy5);
// System.out.println("-----");
// System.out.println(pop.getStringRepresentation());
// System.out.println("-----");
System.out.println(b.bayesianDirichletMetric(pop));
}
}

View File

@ -0,0 +1,111 @@
package eva2.tools.math;
import java.util.LinkedList;
import java.util.List;
public class BayNode {
private int id;
private int numberOfParents = 0;
private double[] pTable = {0.5};
private boolean calculated = false;
private List<Integer> parents = new LinkedList<Integer>();
private List<Integer> children = new LinkedList<Integer>();
public BayNode(int id){
this.id = id;
}
public BayNode(BayNode b){
this.id = b.id;
this.numberOfParents = b.numberOfParents;
this.pTable = b.pTable.clone();
this.parents = new LinkedList<Integer>();
this.children = new LinkedList<Integer>();
for(int i: b.parents){
this.parents.add(i);
}
for(int i: b.children){
this.children.add(i);
}
this.calculated = b.calculated;
}
public Object clone(){
return new BayNode(this);
}
public double getProbability(int i){
return pTable[i];
}
public void generateNewPTable(){
this.pTable = new double[(int) Math.pow(2, this.numberOfParents)];
for(int i=0; i<this.pTable.length; i++){
this.pTable[i] = 0.5;
}
}
public List<Integer> getParents(){
return this.parents;
}
public void addParent(Integer b){
if(!this.parents.contains(b)){
this.parents.add(b);
}
}
public void removeParent(Integer b){
this.parents.remove(b);
}
public List<Integer> getChildren(){
return this.children;
}
public void addChild(Integer b){
if(!this.children.contains(b)){
this.children.add(b);
}
}
public void removeChild(Integer b){
this.children.remove(b);
}
public void setPTable(double[] table){
this.pTable = table;
}
public void setPTable(int i, double v){
this.pTable[i] = v;
}
public void incrNumberOfParents(){
this.numberOfParents++;
}
public void decrNumberOfParents(){
this.numberOfParents--;
}
public int getNumberOfParents(){
return this.numberOfParents;
}
public int getId(){
return this.id;
}
public double[] getPTable(){
return this.pTable;
}
public boolean getCalculated(){
return this.calculated;
}
public void setCalculated(boolean b){
this.calculated = b;
}
}