예제 #1
0
        double ComputeNetwork(ANN nn)
        {
            //Inputs
            int[] inputs = new int[INPUTS];
            for (int i = 0; i < INPUTS; i++)
            {
                //inputs[i] = game.board[i % WIDTH, i / WIDTH];
                if (game.board[i % WIDTH, i / WIDTH] == 0)
                {
                    inputs[i] = 0;
                }
                else
                {
                    inputs[i] = (int)Math.Log(game.board[i % WIDTH, i / WIDTH], 2);
                }
            }

            /*int[] inputs = new int[INPUTS];
             * for (int i = 0; i < 16; i++)
             * {
             *  for (int j = 0; j < 16; j++)
             *  {
             *      if ((int)Math.Log(game.board[i % WIDTH, i / WIDTH], 2) == j + 1)
             *          inputs[i * 16 + j] = 1;
             *      else
             *          inputs[i * 16 + j] = 0;
             *  }
             * }*/

            //Compute values at hidden neurons
            double[] hidden = new double[HIDDEN];
            for (int i = 0; i < HIDDEN; i++)
            {
                hidden[i] = 0;
                for (int j = 0; j < INPUTS; j++)
                {
                    hidden[i] += inputs[j] * nn.neuronLayers[1].neurons[i].weights[j];
                }
                hidden[i] -= nn.neuronLayers[1].neurons[i].weights[INPUTS];
                hidden[i]  = (1 / (float)(1 + Math.Pow(Math.E, -hidden[i])));
            }

            //Compute values at output neurons
            double[] outputs = new double[OUTPUTS];
            for (int i = 0; i < OUTPUTS; i++)
            {
                outputs[i] = 0;
                for (int j = 0; j < HIDDEN; j++)
                {
                    outputs[i] += hidden[j] * nn.neuronLayers[2].neurons[i].weights[j];
                }
                outputs[i] -= nn.neuronLayers[2].neurons[i].weights[HIDDEN];
                outputs[i]  = (1 / (float)(1 + Math.Pow(Math.E, -outputs[i])));
            }

            return(outputs[0]);
        }
예제 #2
0
        public void LoadNetwork(object sender, EventArgs e)
        {
            rootGrid.Children.Clear();
            rootGrid.Children.Add(Score);
            rootGrid.Children.Add(Info);
            rootGrid.Children.Add(saveNetButton);

            // Create a string to read into
            int numWeights = (INPUTS + 1) * HIDDEN + (HIDDEN + 1) * OUTPUTS;

            string[] lines = new string[numWeights + 1];

            //Initialize networks
            for (int i = 0; i < ann.Length; i++)
            {
                ann[i] = new ANN(INPUTS, HIDDEN, OUTPUTS);
            }

            //Read file
            if (System.IO.File.Exists(netPath))
            {
                lines = System.IO.File.ReadAllLines(netPath);
            }
            gen = Convert.ToInt32(lines[2]);
            for (int i = 0; i < ann.Length; i++)
            {
                int ii = 3;
                for (int j = 1; j < 3; j++)
                {
                    for (int k = 0; k < ann[i].neuronLayers[j].neuronNum; k++)
                    {
                        for (int l = 0; l < ann[i].neuronLayers[j].neurons[k].inputNum + 1; l++)
                        {
                            ann[i].neuronLayers[j].neurons[k].weights[l] = Convert.ToDouble(lines[ii]);
                            ii++;
                        }
                    }
                }
            }
            GA.Mutate(ann);

            //Start a game
            game = new Game(rootGrid, random);

            timer          = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(SPEED2);
            timer.Tick    += delegate { Update(); game.UpdateDisplay(); UpdateDisplay(); };
            timer.Start();

            KeyDown += AdjustSpeed;
        }
예제 #3
0
        public void NewNetwork(object sender, EventArgs e)
        {
            rootGrid.Children.Clear();
            rootGrid.Children.Add(Score);
            rootGrid.Children.Add(Info);
            rootGrid.Children.Add(saveNetButton);

            //Create randomized ann's
            for (int i = 0; i < POPULATION; i++)
            {
                //Create ann
                ann[i] = new ANN(INPUTS, HIDDEN, OUTPUTS);
                //For each neuron layer
                for (int j = 0; j < LAYERNUM; j++)
                {
                    //For each neuron in that layer
                    for (int k = 0; k < ann[i].neuronLayers[j].neuronNum; k++)
                    {
                        for (int l = 0; l < ann[i].neuronLayers[j].neurons[k].inputNum + 1; l++)
                        {
                            ann[i].neuronLayers[j].neurons[k].weights[l] = random.NextDouble();
                        }
                    }
                }
            }

            //Start a game
            game = new Game(rootGrid, random);

            timer          = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(SPEED2);
            timer.Tick    += delegate { Update(); game.UpdateDisplay(); UpdateDisplay(); };
            timer.Start();

            KeyDown += AdjustSpeed;
        }
예제 #4
0
파일: GA.cs 프로젝트: mgonzalez92/2048
        //Mate and crossover
        static void Mate(ANN[] ann)
        {
            int    popSize  = ann.Length;
            int    bestSize = popSize / 4;
            Random random   = new Random();
            int    inputs   = ann[0].neuronLayers[0].neuronNum;
            int    hidden   = ann[0].neuronLayers[1].neuronNum;
            int    output   = ann[0].neuronLayers[2].neuronNum;

            //Fittest half of population
            ANN[] best = new ANN[bestSize];
            //Half to replace
            ANN[] children = new ANN[popSize - bestSize];
            for (int i = 0; i < popSize - bestSize; i++)
            {
                children[i] = new ANN(inputs, hidden, output);
            }

            /**********************/
            /*** Find most fit  ***/
            /**********************/
            for (int i = 0; i < bestSize; i++)
            {
                //For each network
                for (int j = 0; j < popSize; j++)
                {
                    //If this network hasn't already been selected
                    if (!best.Contains(ann[j]))
                    {
                        //Set default best network
                        if (best[i] == null)
                        {
                            best[i] = ann[j];
                        }
                        //If this network is better, choose that one
                        else if (ann[j].fitness > best[i].fitness)
                        {
                            best[i] = ann[j];
                        }
                    }
                }
            }

            //Find total fitness of best half
            int totalFitness = 0;

            for (int i = 0; i < bestSize; i++)
            {
                totalFitness += best[i].fitness;
            }

            /******************/
            /*** Crossover  ***/
            /******************/
            for (int i = 0; i < popSize - bestSize; i += 2)
            {
                //Pick two random different parents
                ANN[] parents = new ANN[2];
                for (int j = 0; j < 2; j++)
                {
                    int parentFitness  = random.Next(0, totalFitness);
                    int currentFitness = 0;
                    //Search best half for random parent
                    for (int k = 0; k < bestSize; k++)
                    {
                        currentFitness += best[k].fitness;
                        if (currentFitness > parentFitness)
                        {
                            parents[j] = best[k];
                            break;
                        }
                    }
                }

                //Find number of genes (weights)
                int numWeights = (inputs + 1) * hidden + (hidden + 1) * output;
                int cutLength  = numWeights / 2;

                //Get two slices of genes
                int division1 = random.Next(0, numWeights - cutLength);
                int division2 = division1 + cutLength;

                //Splice together gene slices
                int ii = 0;
                for (int j = 1; j < 3; j++)
                {
                    for (int k = 0; k < ann[i].neuronLayers[j].neuronNum; k++)
                    {
                        for (int l = 0; l < ann[i].neuronLayers[j].neurons[k].inputNum + 1; l++)
                        {
                            if (ii < division1 || ii >= division2)
                            {
                                children[i].neuronLayers[j].neurons[k].weights[l]     = parents[0].neuronLayers[j].neurons[k].weights[l];
                                children[i + 1].neuronLayers[j].neurons[k].weights[l] = parents[1].neuronLayers[j].neurons[k].weights[l];
                            }
                            else
                            {
                                children[i].neuronLayers[j].neurons[k].weights[l]     = parents[1].neuronLayers[j].neurons[k].weights[l];
                                children[i + 1].neuronLayers[j].neurons[k].weights[l] = parents[0].neuronLayers[j].neurons[k].weights[l];
                            }
                            ii++;
                        }
                    }
                }
            }
            //Replace ANN with best half and new children
            best.CopyTo(ann, 0);
            children.CopyTo(ann, best.Length);
        }
예제 #5
0
        void GeneticAlgorithm()
        {
            ANN[] tmp = new ANN[POPULATION];

            //Find best half
            int BEST = POPULATION / 2;

            int[] best = new int[BEST];

            for (int i = 0; i < BEST; i++)
            {
                best[i] = -1;
                for (int j = 0; j < POPULATION; j++)
                {
                    if (!best.Contains(j))
                    {
                        if (best[i] == -1)
                        {
                            best[i] = j;
                        }
                        else if (ann[j].fitness > ann[best[i]].fitness)
                        {
                            best[i] = j;
                        }
                    }
                }
            }

            int selectFitness = 0;

            for (int i = 0; i < BEST; i++)
            {
                selectFitness += ann[best[i]].fitness;
            }

            //Create new ann's
            for (int i = 0; i < POPULATION; i++)
            {
                //Create ann
                tmp[i] = new ANN(INPUTS, HIDDEN, OUTPUTS);

                //Pick two parents
                ANN parent1 = ann[0], parent2 = ann[1];
                int parentFitness  = random.Next(0, selectFitness);
                int currentFitness = 0;
                for (int j = 0; j < BEST; j++)
                {
                    currentFitness += ann[best[j]].fitness;
                    if (parentFitness < currentFitness)
                    {
                        parent1 = ann[best[j]];
                        break;
                    }
                }
                parentFitness  = random.Next(0, selectFitness);
                currentFitness = 0;
                for (int j = 0; j < BEST; j++)
                {
                    currentFitness += ann[best[j]].fitness;
                    if (parentFitness < currentFitness)
                    {
                        parent2 = ann[best[j]];
                        break;
                    }
                }

                //Pick a random division of their weights
                int numWeights = (INPUTS + 1) * HIDDEN + (HIDDEN + 1) * OUTPUTS;
                int division   = 1 + random.Next(0, numWeights - 1);

                //Assign weights
                int ii = 0;
                //For each neuron layer
                for (int j = 0; j < LAYERNUM; j++)
                {
                    //For each neuron in that layer
                    for (int k = 0; k < tmp[i].neuronLayers[j].neuronNum; k++)
                    {
                        for (int l = 0; l < tmp[i].neuronLayers[j].neurons[k].inputNum + 1; l++)
                        {
                            //Parent 1
                            if (ii < division)
                            {
                                tmp[i].neuronLayers[j].neurons[k].weights[l] = parent1.neuronLayers[j].neurons[k].weights[l];
                            }
                            //Parent 2
                            else
                            {
                                tmp[i].neuronLayers[j].neurons[k].weights[l] = parent2.neuronLayers[j].neurons[k].weights[l];
                            }
                            ii++;

                            //Small mutation
                            float mutation = (random.Next(0, 2001) - 1000) / 20000f;
                            tmp[i].neuronLayers[j].neurons[k].weights[l] *= (1 + mutation);
                        }
                    }
                }
            }

            //Assign old ann's to the new population
            for (int i = 0; i < POPULATION; i++)
            {
                ann[i] = tmp[i];
            }
        }