public GenotipoRN[] mutazione(GenotipoRN genotipo, int num)
        {
            GenotipoRN[] r = new GenotipoRN[num];
            Random generatoreCasuale = new Random();
            int numero;

            for (int i = 0; i < num; i++)
            {
                numero = generatoreCasuale.Next(100);
                if (numero < 3)
                    r[i] = mutazioneAggiungiNeurone(genotipo);
                else if (numero < 8)
                    r[i] = mutazioneAggiungiAssone(genotipo);
                else if (numero < 88)
                {
                    numero = generatoreCasuale.Next(100);
                    if (numero < 90)
                        r[i] = mutazioneModificaPesoUniformemente(genotipo);
                    else
                        r[i] = mutazioneModificaPesoRadicalmente(genotipo);
                }
                genotipi.Add(r[i]);
            }

            return r;
        }
        public GestoreRN_NEAT(int input, int output, int perceptronNumber=1)
        {
            contGenotipo = -1;
            contNeuroni = 0;
            contAssoni = 0;
            genotipi = new SortedSet<GenotipoRN>();
            population = new List<GenotipoRN>();
            futurePopulation = new List<GenotipoRN>();

            speciesManager = new SpeciesManager(this);

            perceptron=generaPerceptron(input, output);
            for (int i = 0; i < perceptronNumber;i++)
            {
                speciesManager.addGenotipo(mutazioneModificaPesoRadicalmenteTuttiAssoni(getPerceptron()));
            }

            population = speciesManager.GetListGenotipo();
        }
        public Evolution(Cart cart)
        {
            this.cart = cart;
            evolutionManager = new GestoreRN_NEAT(5, 1, Const.INITIAL_POPULATION);

            int j=0;
            vectorGenotipo=new GenotipoRN[evolutionManager.population.Count];
            foreach (GenotipoRN g in evolutionManager.population)
            {
                vectorGenotipo[j] = g;
                j++;
            }

            ReadyFenotipo += new SetFenotipo(cart.SetFenotipo);
            cart.ReturnFitnessEvent += new Cart.ReturnFitness(finishedSimulation);

            genotipoInTest = evolutionManager.GetGenotipo();
            ReadyFenotipo(new FenotipoRN(genotipoInTest));
        }
 public FenotipoRN(GenotipoRN genotipo)
 {
     neuroni = new SortedList<int,NeuroneF>();
        neuroniA = new List<NeuroneF>();
        neuroniS = new List<NeuroneF>();
        foreach(KeyValuePair<int, GenotipoRN.NeuroneG> k_val in genotipo.neuroni)
        {
        NeuroneF nuovo = new NeuroneF(k_val.Value);
        neuroni.Add(k_val.Key, nuovo);
        }
        foreach (GenotipoRN.NeuroneG neurone in genotipo.neuroniInput)
        neuroniS.Add(neuroni[neurone.neatID]);
        foreach (GenotipoRN.NeuroneG neurone in genotipo.neuroniOutput)
        neuroniA.Add(neuroni[neurone.neatID]);
        foreach (KeyValuePair<int, GenotipoRN.AssoneG> k_val_assone in genotipo.assoni)
        if(k_val_assone.Value.attivo)
            neuroni[k_val_assone.Value.input].addAssone(k_val_assone.Value, neuroni);
        NEAT_numID = 0;
 }
        private GenotipoRN mutazioneModificaPesoRadicalmente(GenotipoRN genotipo)
        {
            GenotipoRN g = new GenotipoRN(genotipo);
            Random generatoreCasuale = new Random();

            int num = generatoreCasuale.Next(g.assoni.Count);

            GenotipoRN.AssoneG assoneCorrente = g.assoni[g.assoni.Keys[num]];
            assoneCorrente.modPeso(1-2*generatoreCasuale.NextDouble());
            g.assoni[g.assoni.Keys[num]] = assoneCorrente;

            return g;
        }
        private GenotipoRN generaPerceptron(int input, int output)
        {
            Random generatoreCasuale = new Random();
            GenotipoRN p = new GenotipoRN();
            p.t = 0;

            for (int i = 0; i < input; i++)
                p.addNeuroneInput(new GenotipoRN.NeuroneG(contNeuroni++, TipoNeurone.NSensor));

            for (int i = 0; i < output; i++)
                p.addNeuroneOutput(new GenotipoRN.NeuroneG(contNeuroni++, TipoNeurone.NActuator));

            for(int i = 0; i < input; i++)
                for (int j = 0; j < output; j++)
                {
                    double peso = generatoreCasuale.NextDouble();
                    p.addAssone(new GenotipoRN.AssoneG(contAssoni, i, j+input, 1 - 2 * peso));
                    contAssoni++;
                }

            genotipi.Add(p);
            return p;
        }
        public GenotipoRN mutazioneModificaPesoUniformemente(GenotipoRN genotipo)
        {
            GenotipoRN g = new GenotipoRN(genotipo);
            Random generatoreCasuale = new Random();

            int num = generatoreCasuale.Next(g.assoni.Count);

            GenotipoRN.AssoneG assoneCorrente = g.assoni[g.assoni.Keys[num]];
            assoneCorrente.modPeso(Utilita.pesoUniforme);
            g.assoni[g.assoni.Keys[num]] = assoneCorrente;

            return g;
        }
        public GenotipoRN mutazioneAggiungiNeurone(GenotipoRN genotipo)
        {
            GenotipoRN g = new GenotipoRN(genotipo);
            Random generatoreCasuale = new Random();

            int num = generatoreCasuale.Next(g.assoni.Count);

            GenotipoRN.AssoneG assoneCorrente = g.assoni[g.assoni.Keys[num]];
            assoneCorrente.attivo = false;
            g.assoni[g.assoni.Keys[num]] = assoneCorrente;

            g.addNeurone(new GenotipoRN.NeuroneG(contNeuroni, TipoNeurone.NHide));
            g.addAssone(new GenotipoRN.AssoneG(contAssoni, g.assoni[g.assoni.Keys[num]].input, contNeuroni, 1));
            contAssoni++;
            g.addAssone(new GenotipoRN.AssoneG(contAssoni, contNeuroni, g.assoni[g.assoni.Keys[num]].output, g.assoni[g.assoni.Keys[num]].peso));
            contAssoni++;
            contNeuroni++;
            return g;
        }
        static void Main(string[] args)
        {
            GenotipoRN gen1, gen2;
            GestoreRN_NEAT gestore = new GestoreRN_NEAT(3, 2);
            ClientNEAT client;

            gen1 = new GenotipoRN();
            gen1.addNeuroneInput(new GenotipoRN.NeuroneG(1, TipoNeurone.NSensor));
            gen1.addNeuroneInput(new GenotipoRN.NeuroneG(2, TipoNeurone.NSensor));
            gen1.addNeuroneInput(new GenotipoRN.NeuroneG(3, TipoNeurone.NSensor));
            gen1.addNeuroneOutput(new GenotipoRN.NeuroneG(4, TipoNeurone.NActuator));
            gen1.addNeuroneOutput(new GenotipoRN.NeuroneG(5, TipoNeurone.NActuator));
            gen1.addNeurone(new GenotipoRN.NeuroneG(6, TipoNeurone.NHide));
            gen1.addAssone(new GenotipoRN.AssoneG(1, 1, 4, 1));
            gen1.addAssone(new GenotipoRN.AssoneG(2, 2, 6, 1));
            gen1.addAssone(new GenotipoRN.AssoneG(3, 6, 4, 1));
            gen1.addAssone(new GenotipoRN.AssoneG(4, 2, 5, 1));
            gen1.addAssone(new GenotipoRN.AssoneG(5, 3, 5, 1));

            gen2 = new GenotipoRN();
            gen2.addNeuroneInput(new GenotipoRN.NeuroneG(1, TipoNeurone.NSensor));
            gen2.addNeuroneInput(new GenotipoRN.NeuroneG(2, TipoNeurone.NSensor));
            gen2.addNeuroneInput(new GenotipoRN.NeuroneG(3, TipoNeurone.NSensor));
            gen2.addNeuroneOutput(new GenotipoRN.NeuroneG(4, TipoNeurone.NActuator));
            gen2.addNeuroneOutput(new GenotipoRN.NeuroneG(5, TipoNeurone.NActuator));
            gen2.addNeurone(new GenotipoRN.NeuroneG(7, TipoNeurone.NHide));
            gen2.addNeurone(new GenotipoRN.NeuroneG(6, TipoNeurone.NHide));
            gen2.addAssone(new GenotipoRN.AssoneG(1, 1, 4, -1));
            gen2.addAssone(new GenotipoRN.AssoneG(2, 2, 6, -1));
            gen2.addAssone(new GenotipoRN.AssoneG(4, 2, 5, -1));
            gen2.addAssone(new GenotipoRN.AssoneG(5, 3, 5, -1));
            gen2.addAssone(new GenotipoRN.AssoneG(6, 3, 7, -1));
            gen2.addAssone(new GenotipoRN.AssoneG(7, 6, 5, -1));
            gen2.addAssone(new GenotipoRN.AssoneG(8, 7, 5, -1));

            //GenotipoRN gen_tmp1 = gestore.getPerceptron();
            //gen1 = gestore.mutazioneAggiungiNeurone(gen_tmp1);
            //GenotipoRN gen_tmp2 = gestore.mutazioneAggiungiNeurone(gen_tmp1);
            //GenotipoRN gen_tmp3 = gestore.mutazioneModificaPesoUniformemente(gen_tmp2);
            //gen2 = gestore.mutazioneAggiungiNeurone(gen_tmp3);

            double d = AlgGenRN.distanza(gen1, gen2);
            GenotipoRN gen3 = new GenotipoRN(gen1, 1, gen2, 2);

            client = new ClientNEAT("127.0.0.1", 13001);
            if (client.connect())
            {
                client.writeConsole("Client connesso\n");
                client.writeConsole("Premi un tasto per inviare il genitore 1");
                Console.ReadKey();
                client.send("IRN");
                gen1.sendNetwork(client.getStream());
                client.receive();
                client.writeConsole("Premi un tasto per inviare il genitore 2");
                Console.ReadKey();
                client.send("IRN");
                gen2.sendNetwork(client.getStream());
                client.receive();
                Console.WriteLine("Distanza tra le reti: " + AlgGenRN.distanza(gen1, gen2));
                client.writeConsole("Premi un tasto per inviare il figlio");
                Console.ReadKey();
                client.send("IRN");
                gen3.sendNetwork(client.getStream());
                client.receive();
                client.writeConsole("Premi un tasto per uscire");
                Console.ReadKey();
                client.disconnect();
            }
            else
            {
                client.writeConsole("Errore di connessione\n");
                Console.ReadKey();
            }
        }
 private void finishedSimulation(int fitness)
 {
     genotipoInTest.Fitness = fitness;
     genotipoInTest = evolutionManager.GetGenotipo();
     ReadyFenotipo(new FenotipoRN(genotipoInTest));
 }
        private void ServerMethod()
        {
            TcpListener server = null;
            NetworkStream stream = null;
            TcpClient client = null;
            Int32 port = 13001, i;
            IPAddress localAddr = IPAddress.Parse("127.0.0.1");
            bool fine = false;
            Byte[] bytes = new Byte[256];
            String data = null;
            //Thread trdBB;

            server = new TcpListener(localAddr, port);
            server.Start();

            while (true)
            {
                fine = false;
                client = server.AcceptTcpClient();
                stream = client.GetStream();

                while (!fine)
                    if ((i = stream.Read(bytes, 0, bytes.Length)) != 0) //legge fino a 256 caratteri dallo stream di rete
                    {
                        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); // interpreta lo stream a blocchi di 1Byte cod.ASCII
                        data.ToLower();
                        /* Qui si mettono i comandi a cui risponde il server */

                        if (data == "IRN")
                        {
                            //data = "Inizio Ricezione";

                            genotipoCorrente = LibreriaRN.GenotipoRN.receiveNetwork(stream);
                            grafo = new GrafoDisegno(genotipoCorrente);
                            data = "Ricezione rete neurale avvenuta\n";
                        }
                        else if (data == "GF")
                        {
                            fenotipo = new FenotipoRN(genotipoCorrente);
                            grafo.AttachFenotipo(fenotipo);
                            data = "Fenotipo generato con successo\n";
                        }
                        else if (data == "INPUT")
                        {
                            String sInput;
                            String[] parsedInput;
                            char[] separatori = { ' ' };
                            if ((i = stream.Read(bytes, 0, bytes.Length)) != 0) //legge fino a 256 caratteri dallo stream di rete
                            {
                                sInput = System.Text.Encoding.ASCII.GetString(bytes, 0, i); // interpreta lo stream a blocchi di 1Byte cod.ASCII
                                parsedInput = sInput.Split(separatori, StringSplitOptions.RemoveEmptyEntries);
                                for (i = 0; i < fenotipo.numNeuroniSensori; i++)
                                    input[i] = Double.Parse(parsedInput[i]);
                                data = "Input ricevuti\n";
                            }
                            else
                                data = "Errore nella ricezione degli input\n";
                        }
                        else if (data == "AGG")
                        {
                            SortedList<int, double> output;
                            data = "";
                            fenotipo.sensori(input);
                            fenotipo.Calcola();
                            output = fenotipo.aggiorna();
                            foreach (KeyValuePair<int, double> k_val in output)
                            {
                                data += k_val.Key.ToString() + ": " + k_val.Value.ToString() + "\n";
                            }
                        }
                        else if (data == "exit" || data == "quit")
                        {
                            fine = true;
                            data = "Server disconnesso...\n";
                        }
                        else
                            data = data.ToUpper();

                        byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
                        stream.Write(msg, 0, msg.Length);
                    }

                // Shutdown and end connection
                if (fine)
                    System.Threading.Thread.Sleep(50); //Aspetta che il client legga

                client.Close();

            }
        }
        public Species(GenotipoRN champion, SpeciesManager manager)
        {
            this.manager = manager;
            this.champion = champion;

            gList = new List<GenotipoRN>();
            gList.Add(champion);
        }
        public bool addGenotipo(GenotipoRN genotipo)
        {
            bool inSpecies = false;
            double distance = AlgGenRN.distanza(champion, genotipo);

            if (distance < Params.SPECIES_MAX_DISTANCE)
            {
                inSpecies = true;
                gList.Add(genotipo);
            }

            return inSpecies;
        }
 public GrafoDisegno(GenotipoRN input)
 {
     Queue<Nodo> coda = new Queue<Nodo>();
     nodi = new SortedList<int, Nodo>();
     //crea i nodi
     foreach (KeyValuePair<int, GenotipoRN.NeuroneG> neurone in input.neuroni)
     {
         Nodo nuovo = new Nodo(neurone.Value.GetId());
         nuovo.livello = 0;
         nuovo.stato = Nodo.StatoVisita.NonVisitato;
         nodi.Add(neurone.Key, nuovo);
     }
     //prepara i neuroni di input
     foreach (GenotipoRN.NeuroneG neurone in input.neuroniInput)
     {
         Nodo nuovoInput = nodi[neurone.GetId()];
         nuovoInput.stato = Nodo.StatoVisita.InCoda;
         coda.Enqueue(nuovoInput);
     }
     //crea gli archi e li inserisce nella lista archi del nodo di partenza
     foreach(GenotipoRN.AssoneG assone in input.assoni)
     {
         Arco nuovo = new Arco(nodi[assone.getOutput()],nodi[assone.getInput()], assone.GetId(), assone.getPeso());
         nodi[assone.getInput()].addArco(nuovo);
     }
     //definisce i livelli come distanza massima da un qualsiasi nodo di input; per far questo fa una visita in ampiezza
     //a partire dai nodi di input
     while (coda.Count > 0)
     {
         Nodo n = coda.Dequeue();
         n.stato = Nodo.StatoVisita.InVisita;
         IEnumerator<Arco> enumerator = n.GetEnumeratorArco();
         while (enumerator.MoveNext())
         {
             Arco a = enumerator.Current;
             if (a.destinazione.livello < (n.livello + 1))
             {
                 a.destinazione.livello = n.livello + 1;
                 if (a.destinazione.livello > maxLivello)
                     maxLivello = a.destinazione.livello;
             }
             if (a.destinazione.stato == Nodo.StatoVisita.NonVisitato)
             {
                 a.destinazione.stato = Nodo.StatoVisita.InCoda;
                 coda.Enqueue(a.destinazione);
             }
         }
         n.stato = Nodo.StatoVisita.Visitato;
     }
     //y_corrente[i] contiene la coordinata y del prossimo neurone al livello i
     int[] y_corrente = new int[maxLivello+1];
     y_corrente[0] = Const.LatoGriglia / 2;
     for (int i = 1; i <= maxLivello; i++)
         y_corrente[i] = y_corrente[i - 1] + Const.LatoGriglia;
     //assegna le posizioni
     foreach (KeyValuePair<int, Nodo> neurone in nodi)
     {
         neurone.Value.posizione = new Vector2(neurone.Value.livello * Const.LatoGriglia + Const.LatoGriglia / 2, y_corrente[neurone.Value.livello]);
         y_corrente[neurone.Value.livello] += Const.LatoGriglia*(maxLivello+1);
     }
     //TODO: portare tutti i neuroni di output al livello massimo, per far sì che vengano tutti allineati. Bisogna però memorizzare
     //separatamente i neuroni di output nel GenotipoRN, analogamente a quanto ho fatto per i neuroni di input.
 }
 public void addAssone(GenotipoRN.AssoneG assone, SortedList<int, NeuroneF> neuroni)
 {
     AssoneF nuovoAssone = new AssoneF(assone, neuroni);
        assoni.Add(nuovoAssone);
        return;
 }
 /// <summary>
 /// Traduce il genotipo passato per argomento
 /// </summary>
 /// <param name="neuroneG">Genotipo da tradurre</param>
 public NeuroneF(GenotipoRN.NeuroneG neuroneG)
 {
     _neatID = neuroneG.neatID;
        memoria = 0;
        _tipo = neuroneG.tipo;
        funzioneSoglia = Threshold.getThresholdFromIndex(neuroneG.thresholdIndex);
        inputP = new List<double>();
        inputF = new List<double>();
        assoni = new List<AssoneF>();
        return;
 }
        private GenotipoRN mutazioneModificaPesoRadicalmenteTuttiAssoni(GenotipoRN genotipo)
        {
            GenotipoRN g = new GenotipoRN(genotipo);
            Random generatoreCasuale = new Random();

            for (int num = 0; num < g.assoni.Count; num++)
            {
                GenotipoRN.AssoneG assoneCorrente = g.assoni[g.assoni.Keys[num]];
                assoneCorrente.modPeso(1 - 2 * generatoreCasuale.NextDouble());
                g.assoni[g.assoni.Keys[num]] = assoneCorrente;
            }
            return g;
        }
        private void listBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            String firma = (String)((ListBox)sender).SelectedItem;

            genotipoSelezionato = genotipi[firma];
            aggiornaDialogBox();
            visualizzaButton.IsEnabled = true;
            addNeuroneButton.IsEnabled = true;
            addAssoneButton.IsEnabled = true;
            modPesoButton.IsEnabled = true;
            //MessageBox.Show(firma, "My Application");
        }
        /// <summary>
        /// Calcola la distanza tra due genotipi come geni_excess*peso1/N + geni_disjoint*peso2/N + differenza_pesi_geni_uguali*peso3 +
        /// neuroni_uguali_con_funzioni_di_soglia_diverse*peso4. Sono considerati geni diversi sia neuroni che assoni
        /// presenti in uno dei due genotipi e non nell'altro. N è il massimo numero di geni nei due genotipi. I pesi sono fissati in Params.
        /// </summary>
        /// <param name="gen1"></param>
        /// <param name="gen2"></param>
        /// <returns></returns>
        public static double distanza(GenotipoRN gen1, GenotipoRN gen2)
        {
            int maxIDNeuroniGen1, maxIDNeuroniGen2, maxIDAssoniGen1, maxIDAssoniGen2;
            double weightDifference = 0;
            int disjointAss = 0, excessAss = 0, disjointNeur = 0, excessNeur = 0, functionDifferences = 0, maxGenes;
            bool end1 = false, end2 = false;
            IEnumerator<KeyValuePair<int, GenotipoRN.NeuroneG>> enumNeurGen1, enumNeurGen2;
            IEnumerator<KeyValuePair<int, GenotipoRN.AssoneG>> enumAssGen1, enumAssGen2;

            maxIDNeuroniGen1 = gen1.maxIDNeuroni;
            maxIDNeuroniGen2 = gen2.maxIDNeuroni;
            maxIDAssoniGen1 = gen1.maxIDAssoni;
            maxIDAssoniGen2 = gen2.maxIDAssoni;

            maxGenes = Math.Max(gen1.numeroNeuroni + gen1.numeroAssoni, gen2.numeroNeuroni + gen2.numeroAssoni);

            enumNeurGen1 = gen1.GetEnumeratorNeuroni();
            enumNeurGen2 = gen2.GetEnumeratorNeuroni();
            enumAssGen1 = gen1.GetEnumeratorAssoni();
            enumAssGen2 = gen2.GetEnumeratorAssoni();

            end1 = !enumNeurGen1.MoveNext();
            end2 = !enumNeurGen2.MoveNext();
            while (!(end1 && end2))
            {
                if (end1)
                {
                    if (enumNeurGen2.Current.Key > maxIDNeuroniGen1)
                        excessNeur++;
                    else
                        disjointNeur++;
                    end2 = !enumNeurGen2.MoveNext();
                }
                else if (end2)
                {
                    if (enumNeurGen1.Current.Key > maxIDNeuroniGen2)
                        excessNeur++;
                    else
                        disjointNeur++;
                    end1 = !enumNeurGen1.MoveNext();
                }
                else
                {
                    if (enumNeurGen1.Current.Key == enumNeurGen2.Current.Key)
                    {
                        if (enumNeurGen1.Current.Value.thresholdIndex != enumNeurGen2.Current.Value.thresholdIndex)
                            functionDifferences++;
                        end1 = !enumNeurGen1.MoveNext();
                        end2 = !enumNeurGen2.MoveNext();
                    }
                    else if (enumNeurGen1.Current.Key > enumAssGen2.Current.Key)
                    {
                            /*ho trovato un gene in gen1 successivo al gene corrente di gen2 però ho altri geni in gen2 con neatID maggiore
                             *-> determina se è excess o disjoint e avanza l'enumerator più indietro, cioè gen2
                             */
                        if (!gen1.contieneNeuroneID(enumNeurGen2.Current.Key))
                            if (enumNeurGen2.Current.Key > maxIDNeuroniGen1)
                                excessNeur++;
                            else
                                disjointNeur++;
                        end2 = !enumNeurGen2.MoveNext();
                    }
                    else //if(enumNeurGen1.Current.Key < enumAssGen2.Current.Key)
                    {
                        if (!gen2.contieneNeuroneID(enumNeurGen1.Current.Key))
                            if (enumNeurGen1.Current.Key > maxIDNeuroniGen2)
                                excessNeur++;
                            else
                                disjointNeur++;
                        end1 = !enumNeurGen1.MoveNext();
                    }
                }
            }

            end1 = !enumAssGen1.MoveNext();
            end2 = !enumAssGen2.MoveNext();
            while (!(end1 && end2))
            {
                if (end1)
                {
                    if (enumAssGen2.Current.Key > maxIDAssoniGen1)
                        excessAss++;
                    else
                        disjointAss++;
                    end2 = !enumAssGen2.MoveNext();
                }
                else if (end2)
                {
                    if (enumAssGen1.Current.Key > maxIDAssoniGen2)
                        excessAss++;
                    else
                        disjointAss++;
                    end1 = !enumAssGen1.MoveNext();
                }
                else
                {
                    if (enumAssGen1.Current.Key == enumAssGen2.Current.Key)
                    {
                        weightDifference += Math.Abs(enumAssGen1.Current.Value.peso - enumAssGen2.Current.Value.peso);
                        end1 = !enumAssGen1.MoveNext();
                        end2 = !enumAssGen2.MoveNext();
                    }
                    else if (enumAssGen1.Current.Key > enumAssGen2.Current.Key)
                    {
                        if (!gen1.contieneAssoneID(enumAssGen2.Current.Key))
                            if (enumAssGen2.Current.Key > maxIDAssoniGen1)
                                excessAss++;
                            else
                                disjointAss++;
                        end2 = !enumAssGen2.MoveNext();
                    }
                    else //if(enumAssGen1.Current.Key < enumAssGen2.Current.Key)
                    {
                        if (!gen2.contieneAssoneID(enumAssGen1.Current.Key))
                            if (enumAssGen1.Current.Key > maxIDAssoniGen2)
                                excessAss++;
                            else
                                disjointAss++;
                        end1 = !enumAssGen1.MoveNext();
                    }
                }
            }
            return (excessAss + excessNeur) * Params.excessGenesWeight/maxGenes + (disjointAss + disjointNeur) * Params.disjointGenesWeight/maxGenes + weightDifference * Params.weightDifferenceWeight + functionDifferences * Params.functionDifferenceWeight;
        }
 public AssoneF(GenotipoRN.AssoneG assoneG, SortedList<int, NeuroneF> neuroni)
 {
     neuroneLink = neuroni[assoneG.output];
        peso = assoneG.peso;
        return;
 }
        public GenotipoRN mutazioneAggiungiAssone(GenotipoRN genotipo)
        {
            GenotipoRN g = new GenotipoRN(genotipo);
            Random generatoreCasuale = new Random();
            bool esiste = false;

            int neurone1;
            int neurone2;

            int indice = genotipo.neuroni.Count;

            /* ho impedito la possibilità di creare assoni che hanno come sorgente un nodo di output o come destinazione un nodo di input
             * perché oltre a dare problemi di visualizzazione mi sembra abbiano poco senso: credo che i neuroni di input debbano semplicemente
             * riportare gli input alla rete (secondo me senza farci nessuna elaborazione però si può consentire che il neurone di input abbia una
             * funzione di soglia disabilitando Params.transparentInput) così come i neuroni di output debbano solo portare le uscite agli attuatori.
             */
            do
                neurone1 = genotipo.neuroni.Keys[generatoreCasuale.Next(indice)];
            while (genotipo.neuroni[neurone1].tipo == TipoNeurone.NActuator);
            do
                neurone2=genotipo.neuroni.Keys[generatoreCasuale.Next(indice)];
            while (genotipo.neuroni[neurone2].tipo == TipoNeurone.NSensor);

            for (int i = 0; i < g.numeroAssoni; i++)
                /* io annullerei la possibilità di raddoppio perché trasformerebbe una mutazione del tipo "aggiungi assone" in una "modifica peso"
                 * anche se occorrerebbe gestire in qualche modo il caso in cui si vorrebbe creare un assone già esistente. Continuando a generare a caso
                 * input e output finché non si trovano due neuroni ancora non collegati si rischia infatti o di metterci molto tempo o peggio di entrare
                 * in un ciclo infinito se tutti i collegamenti fossero già stabiliti, situazioni non impossibili con pochi neuroni.
                 */
                if (g.assoni[i].testaCollegamento(neurone1, neurone2))
                {
                    GenotipoRN.AssoneG assone = g.assoni[g.assoni.Keys[i]];
                    assone.raddoppia();
                    g.assoni[g.assoni.Keys[i]] = assone;
                    esiste = true;
                    Console.WriteLine("Raddoppio " + neurone1 + " - " + neurone2);
                    break;
                }

            if (!esiste)
            {
                g.addAssone(new GenotipoRN.AssoneG(contAssoni, neurone1, neurone2, generatoreCasuale.NextDouble()));
                contAssoni++;
            }

            return g;
        }
        public void GetNextGeneration(List<GenotipoRN> poolCrossingOver, int numberMax)
        {
            Random r = new Random();
            GenotipoRN parent1 = null;
            GenotipoRN parent2 = null;

            gList.Sort();

            int n= gList.Count;
            int gaussNumber = (n * (n + 1)) / 2;
            int extractNumber;
            int generateCreatureNumber=1;

            poolCrossingOver.Add(gList.First());

            while (generateCreatureNumber < (3*numberMax/4 -1))
            {
                extractNumber=r.Next(gaussNumber);
                int accumulator = n;
                for (int i = 0; i < gList.Count; i++)
                {
                    if (extractNumber < accumulator)
                    {
                        parent1 = gList.ElementAt(i);
                        break;
                    }
                    else
                        accumulator += gList.Count - i - 1;
                }

                extractNumber = r.Next(gaussNumber);
                accumulator = n;
                for (int i = 0; i < gList.Count; i++)
                {
                    if (extractNumber < accumulator)
                    {
                        parent2 = gList.ElementAt(i);
                        break;
                    }
                    else
                        accumulator += gList.Count - i - 1;
                }
                GenotipoRN child = new GenotipoRN(parent1, parent1.Fitness, parent2, parent2.Fitness);

                poolCrossingOver.Add(child);
                generateCreatureNumber++;
            }

            while (generateCreatureNumber < numberMax)
            {
                GenotipoRN randomGenotipo = null;
                extractNumber = r.Next(gaussNumber);
                int accumulator = n;
                for (int i = 0; i < gList.Count; i++)
                {
                    if (extractNumber < accumulator)
                    {
                        randomGenotipo = gList[i];
                        break;
                    }
                    else
                        accumulator += gList.Count - i - 1;
                }

                 poolCrossingOver.Add(manager.gestore.mutazione(randomGenotipo, 1)[0]);

            }
        }
 public GrafoDisegno(GenotipoRN input)
 {
     Queue<Nodo> coda = new Queue<Nodo>();
     nodi = new SortedList<int, Nodo>();
     //crea i nodi
     foreach (KeyValuePair<int, GenotipoRN.NeuroneG> neurone in input.neuroni)
     {
         Nodo nuovo = new Nodo(neurone.Value.neatID, neurone.Value.thresholdIndex);
         nuovo.livello = 0;
         nuovo.stato = Nodo.StatoVisita.NonVisitato;
         nuovo.tipo = TipoNeurone.NHide;
         nodi.Add(neurone.Key, nuovo);
     }
     //prepara i neuroni di input
     foreach (GenotipoRN.NeuroneG neurone in input.neuroniInput)
     {
         Nodo nuovoInput = nodi[neurone.neatID];
         nuovoInput.stato = Nodo.StatoVisita.InCoda;
         nuovoInput.tipo = TipoNeurone.NSensor;
         coda.Enqueue(nuovoInput);
     }
     foreach (GenotipoRN.NeuroneG neurone in input.neuroniOutput)
         nodi[neurone.neatID].tipo = TipoNeurone.NActuator;
     //crea gli archi e li inserisce nella lista archi del nodo di partenza
     foreach(KeyValuePair<int,GenotipoRN.AssoneG> assone in input.assoni)
     {
         if (!assone.Value.attivo)
             continue;
         Arco nuovo = new Arco(nodi[assone.Value.output],nodi[assone.Value.input], assone.Value.neatID, assone.Value.peso);
         nodi[assone.Value.input].addArco(nuovo);
     }
     //definisce i livelli come distanza massima da un qualsiasi nodo di input; per far questo fa una visita in ampiezza
     //a partire dai nodi di input
     while (coda.Count > 0)
     {
         Nodo n = coda.Dequeue();
         n.stato = Nodo.StatoVisita.InVisita;
         IEnumerator<Arco> enumerator = n.GetEnumeratorArco();
         while (enumerator.MoveNext())
         {
             Arco a = enumerator.Current;
             if ((a.destinazione.livello <= n.livello) && (a.destinazione.stato != Nodo.StatoVisita.Visitato) && (a.destinazione.tipo != TipoNeurone.NActuator) && (a.destinazione != a.partenza))
             {
                 a.destinazione.livello = n.livello + 1;
                 if (a.destinazione.livello > maxLivello)
                     maxLivello = a.destinazione.livello;
             }
             if (a.destinazione.stato == Nodo.StatoVisita.NonVisitato)
             {
                 a.destinazione.stato = Nodo.StatoVisita.InCoda;
                 coda.Enqueue(a.destinazione);
             }
         }
         n.stato = Nodo.StatoVisita.Visitato;
     }
     foreach (GenotipoRN.NeuroneG neurone in input.neuroniOutput)
         nodi[neurone.neatID].livello = maxLivello+1;
     maxLivello++;
     //y_corrente[i] contiene la coordinata y del prossimo neurone al livello i
     int[] y_corrente = new int[maxLivello+1];
     y_corrente[0] = Const.LatoGriglia / 2;
     for (int i = 1; i <= maxLivello; i++)
         y_corrente[i] = y_corrente[i - 1] + Const.LatoGriglia;
     //assegna le posizioni
     foreach (KeyValuePair<int, Nodo> neurone in nodi)
     {
         neurone.Value.posizione = new Vector2(neurone.Value.livello * Const.LatoGriglia + Const.LatoGriglia / 2, y_corrente[neurone.Value.livello]);
         y_corrente[neurone.Value.livello] += Const.LatoGriglia*(maxLivello+1);
     }
 }
        public void addGenotipo(GenotipoRN genotipo)
        {
            bool speciesFind = false;
            foreach (Species s in speciesList)
            {
                if (s.addGenotipo(genotipo))
                {
                    speciesFind = true;
                    break;
                }
            }

            if (!speciesFind)
                speciesList.Add(new Species(genotipo, this));
        }