public bool getTransition(int i, int j, CAState cas) { int neighbors = (cas.getValue(i - 1, j - 1)? 1: 0) + (cas.getValue(i - 1, j)? 1: 0) + (cas.getValue(i - 1, j + 1)? 1: 0) + (cas.getValue(i, j - 1)? 1: 0) + (cas.getValue(i, j + 1)? 1: 0) + (cas.getValue(i + 1, j - 1)? 1: 0) + (cas.getValue(i + 1, j)? 1: 0) + (cas.getValue(i + 1, j + 1)? 1: 0); if (cas.getValue(i, j)) { if (neighbors < 2 || neighbors > 3) { return(false); } return(true); } else if (neighbors == 3) { return(true); } return(false); }
public CAState getTransition(CAState a) { CAState r = new CAState(a); getTransition(a, r); return(r); }
public FixedGA(CAState archetype, int population_size, int period, CARuleSet rule_set, float outer_mutation_rate, float inner_mutation_rate, float cull_rate, int max_iterations) { this.archetype = archetype; this.period = period; this.rule_set = rule_set; this.outer_mutation_rate = outer_mutation_rate; this.inner_mutation_rate = inner_mutation_rate; this.cull_rate = cull_rate; this.max_iterations = max_iterations; population = new CAState[population_size]; n_cull = (int)(cull_rate * population.Length); fitness_weights = new float[period]; float fwt = 0.0f; for (int i = 0; i < fitness_weights.Length; ++i) { float t = (float)(i + 1) / (fitness_weights.Length); fitness_weights[i] = 0.75f - (float)(Math.Sin(10 * t / Math.PI)); fwt += Math.Abs(fitness_weights[i]); } for (int i = 0; i < fitness_weights.Length; ++i) { fitness_weights[i] /= fwt; } }
public void getTransition(CAState a, CAState b, int n) { CAState temp = new CAState(a); for (int i = 0; i < n; ++i) { getTransition(temp, b); temp.copyFrom(b); } }
public void getTransition(CAState a, CAState b) { for (int i = 0; i < a.Width; ++i) { for (int j = 0; j < a.Height; ++j) { b[i, j] = getTransition(i, j, a); } } }
public float getHeat(CAState a, int p) { CAState b = new CAState(a); CAState c = new CAState(a); float r = 0.0f; for (int i = 0; i < p; ++i) { getTransition(b, c); r += b.getDifference(c); b.copyFrom(c); } return(r / p); }
public int getPeriod(CAState a) { CAState b = new CAState(a); CAState c = new CAState(a); for (int i = 0; i < 1000; ++i) { getTransition(b, c); b.copyFrom(c); if (b.getRelativeDifference(a) == 0) { return(i + 1); } } return(0); }
//private void evaluateFitness(CAState state) //{ // CAState temp0 = new CAState(); // CAState temp1 = new CAState(); // temp0.copyFrom(state); // for (int k=0; k<period; ++k) // { // rule_set.getTransition(temp0, temp1); // temp0.copyFrom(temp1); // } // float oscillatorness = 1.0f - temp0.getDifference(state); // //float density = (float)(population[j].numberOfLiveCells()) / (CAState.Width * CAState.Height); // int nas = state.numberOfLiveCells(); // int min_nas = 20; // float density = (nas > min_nas) ? 1.0f : nas / min_nas; // float t = 0.75f; // state.fitness = t * oscillatorness + (1.0f - t) * density; //} // no state should look more like the first than the end state private void evaluateFitness(CAState state) { float oscillatorness = 0.0f; CAState temp0 = new CAState(state); CAState temp1 = new CAState(state); float[] f = new float[period]; for (int k = 0; k < period; ++k) { rule_set.getTransition(temp0, temp1); temp0.copyFrom(temp1); f[k] = fitness_weights[k] * (1.0f - temp0.getRelativeDifference(state)); oscillatorness += f[k]; } float final_difference = temp0.getRelativeDifference(state); if (final_difference == 0) { state.fitness = 1.0f; return; } //oscillatorness = 1.0f - final_difference; //float oscillatorness = Math.Max(0, 1.0f - final_difference - 20*(final_difference - min_difference)); //if (final_difference == min_difference) //{ // oscillatorness = 1.0f - final_difference + (final_difference - min_difference); //} //else //{ // oscillatorness = Math.Max(1.0f - 10.0f*min_difference, 0); //} //float density = (float)(population[j].numberOfLiveCells()) / (CAState.Width * CAState.Height); int nas = state.numberOfLiveCells(); int min_nas = 20; float density = (nas > min_nas) ? 1.0f : nas / min_nas; float t = 0.8f; state.fitness = t * oscillatorness + (1.0f - t) * density; }
public static void printOscillator(CAState c, CARuleSet rule_set) { CAState temp0 = new CAState(c); CAState temp1 = new CAState(c); while (true) { Console.WriteLine(temp0.ToString()); Console.WriteLine(); rule_set.getTransition(temp0, temp1); if (temp1.getRelativeDifference(c) == 0) { break; } temp0.copyFrom(temp1); } }
public static void saveImages(CAState c, CARuleSet rule_set, String path) { CAState temp0 = new CAState(c); CAState temp1 = new CAState(c); int i = 0; while (true) { Bitmap image = temp0.toImage(c.Width * 100, c.Height * 100); image.Save(path + "/" + i + ".bmp"); rule_set.getTransition(temp0, temp1); if (temp1.getRelativeDifference(c) == 0) { break; } temp0.copyFrom(temp1); ++i; } }
// simple breeding model - randomly choose each cell from either A or B private CAState breed(CAState a, CAState b, Random rng) { CAState c = new CAState(a); for (int i = 0; i < c.Width; ++i) { for (int j = 0; j < c.Height; ++j) { if (rng.Next() % 2 == 0) { c.setValue(i, j, a.getValue(i, j)); } else { c.setValue(i, j, b.getValue(i, j)); } } } return(c); }
static void Main() { //CAState.Width = 10; //CAState.Height = 10; //CAState.Wrap_Mode = CAState.WrapMode.Extend; //int population_size = 200; //int period = 2; //CARuleSet rule_set = new CARuleSet(); //float mutation_rate = 0.01f; //float cull_rate = 0.5f; //float crossover_rate = 1.0f / (CAState.Width * CAState.Height); //int max_iterations = 10000; //int seed = 1102260512; //(int)(DateTime.Now.Ticks); CAState archetype = new CAState(12, 12, CAState.WrapMode.Extend); int population_size = 100; int period = 2; CARuleSet rule_set = new CARuleSet(); float outer_mutation_rate = 0.5f; float inner_mutation_rate = 0.7f; float cull_rate = 0.25f; int max_iterations = 10000; int seed = (int)(DateTime.Now.Ticks); FixedGA ga = new FixedGA(archetype, population_size, period, rule_set, outer_mutation_rate, inner_mutation_rate, cull_rate, max_iterations); StringBuilder sb = new StringBuilder(); sb.AppendLine("CA dimensions: " + archetype.Width + "x" + archetype.Height); sb.AppendLine("CA wrap_mode: " + archetype.wrap_mode); sb.AppendLine("population size: " + population_size); sb.AppendLine("period: " + period); sb.AppendLine("outer mutation rate: " + outer_mutation_rate); sb.AppendLine("inner mutation rate: " + inner_mutation_rate); sb.AppendLine("cull rate: " + cull_rate); sb.AppendLine("max iterations: " + max_iterations); sb.AppendLine("seed: " + seed); ga.run(seed, sb); //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new MainWindow()); //CARuleSet crs = new CARuleSet(); //String name = CAState.getRandomOscillatorName(); //Console.WriteLine(name); //CAState c = CAState.loadOscillatorFromName(name); //c.addPadding(2, 2); //int period = crs.getPeriod(c); //float heat = crs.getHeat(c, period); //Console.WriteLine("period " + period); //Console.WriteLine("heat " + heat); //CAState temp0 = new CAState(c); //CAState temp1 = new CAState(c); //for (int i=0; i<period; ++i) //{ // Console.WriteLine(temp0.ToString()); // crs.getTransition(temp0, temp1); // temp0.copyFrom(temp1); //} }
public void run(int seed, StringBuilder sb) { // initialize the population Random rng = new Random(seed); for (int i = 0; i < population.Length; ++i) { population[i] = new CAState(archetype); population[i].randomize(rng); evaluateFitness(population[i]); } bool stop = false; for (int i = 0; i < max_iterations; ++i) { float mean, variance, min, max; Utility.getStatistics(population, out mean, out variance, out min, out max); String float_pattern = "{0:0.0000}"; String mv_txt = i + "," + String.Format(float_pattern, mean) + "," + String.Format(float_pattern, variance) + "," + String.Format(float_pattern, min) + "," + String.Format(float_pattern, max); sb.AppendLine(mv_txt); Console.WriteLine(mv_txt); int n_om = (int)(outer_mutation_rate * population.Length); int n_im = (int)(inner_mutation_rate * archetype.Width * archetype.Height); for (int j = 0; j < n_om; ++j) { //population[j].randomize(rng); CAState state = population[rng.Next() % population.Length]; //CAState state = population[j]; for (int k = 0; k < n_im; ++k) { state[rng.Next() % archetype.Width, rng.Next() % archetype.Height] = (rng.Next() % 2 == 1); } evaluateFitness(state); } Array.Sort(population); for (int j = 0; j < n_cull; ++j) { population[j] = breed(population[population.Length - j - 1], population[population.Length - j - 2], rng); evaluateFitness(population[j]); if (population[j].fitness == 1) { //Console.WriteLine(oscillatorness + "," + density); //print(population[j]); String path = Utility.createNewFolder("./"); Utility.saveImages(population[j], rule_set, path); Utility.writeFile(sb, path, "data"); stop = true; break; } } if (stop) { break; } } }