示例#1
0
        /// <summary>
        /// Metoda, která vytvoří základní generaci CEST
        /// </summary>
        /// <param name="pocet">Počet CEST v počáteční i dalších generacích</param>
        public void VytvorZakladniGeneraci(int pocet)
        {
            for (int j = 0; j < pocet; j++)
            {
                // Vytvarim novy seznam mest, podle pozedavku. Tedy novou cestu, ktera bude obsahovat 35 mest
                List <Mesto> novaCesta = new List <Mesto>();
                List <int>   vyberMest = new List <int>();
                // Pouze seznam abych vytvarel nova mesta a nebyli na ceste nektera mesta vicekrat
                for (int i = 0; i < 35; i++)
                {
                    vyberMest.Add(i);
                }
                for (int i = 0; i < 35; i++)
                {
                    // Vyberu ze zbyvajicich moznosti nejake ID a podle toho vytvorim dane mesto
                    int pomocna = vyberMest[random.Next(vyberMest.Count)];
                    novaCesta.Add(new Mesto(mesta[pomocna].Id, mesta[pomocna].Nazev, SpocitejVzdalenosti(mesta[pomocna].Id)));
                    // Smazu vybrane ID, protoze by se mi opakovali mesta
                    vyberMest.RemoveAt(vyberMest.IndexOf(pomocna));
                }
                // Přidám novou CESTU do generace a zvýším IDcesty
                posledniCesta = new Cesta(novaCesta, IdCesta);
                IdCesta++;
                Generace.Add(posledniCesta);
            }

            VykresliInfo(0, 1);
        }
示例#2
0
        /// <summary>
        /// Fitnes funkce pro genetický algoritmus. Ohodnotím potomky a poté roztočím váženou ruletu, která preferuje jedince s kratší vzdáleností.
        /// </summary>
        public void VypocitejKvalitu()
        {
            IdCesta = 0;
            double CelkovaVzdalenost = 0;
            // Instance randomu, pro náhodný výběr
            Random       random           = new Random();
            List <Cesta> UpravenaGenerace = new List <Cesta>();

            // Projdu všechny potomky a sečtu jejich vzdálenosti, abych měl celkovou vzdálenost všech potomků pro vytvoření poměru
            foreach (Cesta c in Generace)
            {
                CelkovaVzdalenost += (1 / c.Vzdalenost);
            }
            // Proměnná do která se postupně zvyšuje, tak aby bylo možné stanovit spodní hranici daného potomka na ruletě
            double Vzdalenost = 0;

            // Projdu všechny potomky a každému spočítám spodní a horní hranici. Tedy úsek, který zabírá z celkové vzdálenosti
            foreach (Cesta c in Generace)
            {
                // Násobek je pouze pro to, aby byla dosažena dostatečná velikost každého prvku
                if (Vzdalenost != 0)
                {
                    c.MinRozsah = (int)Math.Floor((Vzdalenost / CelkovaVzdalenost) * 5000);
                }
                else
                {
                    c.MinRozsah = 0;
                }
                // 1/vzdálenost, abych dosáhl toho, že nejlepší potomci (nejkratší vzdálenosti) zabírají více než ty s větší vzdáleností
                Vzdalenost += (1 / c.Vzdalenost);
                c.MaxRozsah = (int)Math.Floor((Vzdalenost / CelkovaVzdalenost) * 5000);
            }
            // Náhodně ,,trefuji,, rozsahy, dokud netrefím stejný počet potomků jako měla původní generace
            while (UpravenaGenerace.Count < PocetPotomku)
            {
                int hodnota = random.Next(5001);

                for (int i = 0; i < PocetPotomku; i++)
                {
                    Cesta aktualniCesta = Generace[i];
                    if (hodnota > aktualniCesta.MinRozsah && hodnota < aktualniCesta.MaxRozsah)
                    {
                        UpravenaGenerace.Add(new Cesta(aktualniCesta.seznamMest, IdCesta));
                        IdCesta++;
                        break;
                    }
                }
            }
            // Předám referenci na novou kolekci původní kolekci
            Generace = UpravenaGenerace;
            // Zobrazím informace do konzole
            VykresliInfo(IdGenerace, 0);
        }
示例#3
0
        // Konstruktor ve kterém je vše potřebné zakomponováno, proto postačí vytvoření instance třídy
        public GenetickyAlgoritmus()
        {
            mapaVzdalenosti = new float[35, 35];
            mesta           = new List <Mesto>();
            Generace        = new List <Cesta>();
            random          = new Random();
            //
            string[] nazvy = DefinujMapuVzdalenosti();
            // Definuji si zakladni seznam mest, podle puvodniho poradi
            for (int i = 0; i < 35; i++)
            {
                mesta.Add(new Mesto(i, nazvy[i], SpocitejVzdalenosti(i)));
            }
            // Vytvoření základní generace, se kterou se dále prováději kroky mutace, křížení a ohodnocení
            VytvorZakladniGeneraci(PocetPotomku);
            // Pocet vytvorenych generaci
            VytvorNovouGeneraci(1000);
            Console.WriteLine(" ------------------------------ Nejlepsi nalezena cesta ------------------------------ ");
            int ind = 0;

            // Zobrazení nalezeného nejlepšího řešení
            foreach (Mesto m in nejlepsiCesta.seznamMest)
            {
                ind++;
                Console.Write("|" + m.Nazev + "\t\t" + m.Id + "|");
                if (ind % 4 == 0)
                {
                    Console.Write("\n");
                }
            }
            Console.Write("\n Vzdalenost teto cesty je: {0} km", nejlepsiCesta.Vzdalenost);

            // Vypis vsech prvku v posledni generaci, pozdeji smazat. Pouze pro ucely testovani
            foreach (Cesta c in Generace)
            {
                Cesta puvodni    = c;
                int   pocetShody = 0;
                foreach (Cesta ces in Generace)
                {
                    if (c.Vzdalenost == ces.Vzdalenost)
                    {
                        pocetShody++;
                    }
                }
                Console.WriteLine("{0} {1}", pocetShody, puvodni.Vzdalenost);
            }
        }
示例#4
0
        /// <summary>
        /// Metoda, která vykreslí základní informace o právě probíhané události.
        /// </summary>
        /// <param name="generace">Číslo generace</param>
        /// <param name="vstup">0 - kvalita, 1 - nova generace, 2 - mutace</param>
        private void VykresliInfo(int generace, byte vstup)
        {
            int soucetIDmest = 0;

            // Smažu konzoli
            Console.Clear();
            // Pouze podmínka, jaká hlavička se bude v konzoli vykreslovat, aby bylo vidět jaká operace probíhá
            if (vstup == 0)
            {
                Console.WriteLine("************************|    Kvalita   |*************************");
            }
            else if (vstup == 1)
            {
                Console.WriteLine("************************|    NovaGEN   |*************************");
            }
            else if (vstup == 2)
            {
                Console.WriteLine("************************|    MUTACE    |*************************");
            }

            double cesta = 0;

            // Výpočet celkové vzdálenosti všech CEST v generaci
            foreach (Cesta c in Generace)
            {
                cesta += c.Vzdalenost;
            }
            // Seřazení kolekce Generace, vzestupně
            IEnumerable <Cesta> serazene = Generace.OrderBy(a => a.Vzdalenost);
            // Uložení nejvyšší vzdálenosti potomka - CESTY
            float TOP = serazene.Last().Vzdalenost;
            // Uložení nejnižší vzdálenosti potomka - CESTY
            float DOWN = serazene.First().Vzdalenost;
            // Vyčtení nejlepší CESTY
            Cesta novaNejvyssi = serazene.First();

            if (nejlepsiCesta == null)
            {
                nejlepsiCesta = novaNejvyssi;
            }
            if (novaNejvyssi.Vzdalenost < nejlepsiCesta.Vzdalenost)
            {
                nejlepsiCesta = novaNejvyssi;
            }

            int pocetNejvyssich = 0;
            int pocetNejnizsich = 0;

            // Výpočet počtu nejlepších jedinců a současně nejhorších, pro kontrolu koncentrace nejlepších a nejhorších
            foreach (Cesta c in Generace)
            {
                if (c.Vzdalenost == TOP)
                {
                    pocetNejvyssich++;
                }
                else if (c.Vzdalenost == DOWN)
                {
                    pocetNejnizsich++;
                }
            }
            // Součet ID měst, pouze kontrola pro objevení duplicity města v kolekci
            foreach (Cesta c in Generace)
            {
                foreach (Mesto m in c.seznamMest)
                {
                    soucetIDmest += m.Id;
                }
            }

            int    hraniceSpodniHorni = Generace.Count / 5;
            double spodniSkupina      = 0;
            double horniSkupina       = 0;
            int    inc = 0;

            // Nalezení CEST, které spadají do horních a spodních 20 % rozsahu aktuální generace
            foreach (Cesta c in serazene)
            {
                inc++;
                spodniSkupina += c.Vzdalenost;
                if (inc > hraniceSpodniHorni)
                {
                    break;
                }
            }
            inc = 0;
            foreach (Cesta c in serazene)
            {
                inc++;
                if (inc > Generace.Count - hraniceSpodniHorni)
                {
                    horniSkupina += c.Vzdalenost;
                }
            }
            // Výpočet průměru horní a spodních 20 % jedinců
            spodniSkupina = spodniSkupina / (double)hraniceSpodniHorni;
            spodniSkupina = Math.Floor(spodniSkupina);
            horniSkupina  = horniSkupina / (double)hraniceSpodniHorni;
            horniSkupina  = Math.Floor(horniSkupina);

            Console.WriteLine("------------------------|  GENERACE {5}  |------------------------\n" +
                              "     -- Celkova vzdalenost teto generace je:\t{0}\n" +
                              "     -- Nejvyssi vzdalenost je:\t\t\t{1}\n" +
                              "     -- A kolekce jich obsahuje:\t\t{2}\n" +
                              "     -- A jejich PRUMER je:\t\t\t{7}\n\n\n" +
                              "     -- Nejnizsi vzdalenost je:\t\t\t{3}\n" +
                              "     -- A kolekce jich obsahuje:\t\t{4}\n" +
                              "     -- A jejich PRUMER je:\t\t\t{8}\n" +
                              "     -- Soucet mest u potomku je:\t\t{6}\n"
                              , cesta, serazene.Last().Vzdalenost, pocetNejvyssich, serazene.First().Vzdalenost, pocetNejnizsich
                              , generace, soucetIDmest, horniSkupina, spodniSkupina);
            // Uspání vlákna pro čitelnost výpisu
            Thread.Sleep(50);
        }