예제 #1
0
        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);
        }
예제 #2
0
        public CAState getTransition(CAState a)
        {
            CAState r = new CAState(a);

            getTransition(a, r);
            return(r);
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
 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);
         }
     }
 }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
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;
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        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;
            }
        }
예제 #11
0
        // 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);
        }
예제 #12
0
        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);
            //}
        }
예제 #13
0
        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;
                }
            }
        }