예제 #1
0
 private void Trim(FunctionTree geneNode, int level)
 {
     // i ako je nivo 0 tada
     if (level == 1 || geneNode.SubFunctionTree == null)
     {
         // odstrani potomke
         if (geneNode.SubFunctionTree != null)
         {
             geneNode.SubFunctionTree.Clear();
             //postavi null za potimke da se delocira memorija
             geneNode.SubFunctionTree = null;
         }
         // a cvor funkcija generiraj kao terminal
         if (geneNode.NodeValue >= 2000)
         {
             GenerateGene(geneNode, false);
         }
     }
     else //Ako nivo nije 0 tada udji u novo za 1 manji
     {
         // prolazi kroz potomke sa novoom za 1 manjim
         for (int i = 0; i < geneNode.SubFunctionTree.Count; i++)
         {
             Trim(geneNode.SubFunctionTree[i], level - 1);
         }
     }
 }
예제 #2
0
        public void CrossOverHromosomes(FunctionTree c1, FunctionTree c2)
        {
            FunctionTree node = c1;// root u privremenu varijablu od koje se bira slucajno potomak

            while (true)
            {
                if (node.SubFunctionTree == null)
                {
                    node = Swap(node, c2);
                    break;
                }
                // slucajno izabrani broj
                int r = rand.Next(node.SubFunctionTree.Count);
                //Slucajno izabrani potomak
                FunctionTree child = node.SubFunctionTree[r];


                //Ako slucajno izabrani potomak nema potomaka onda se on ukrsta ili ako se generise slucajno broj 0
                if ((child.SubFunctionTree == null) || (rand.Next(gpParameters.maxCossoverLevel) == 0 /*(int)(gpParameters.maxCossoverLevel/2)*/))
                {
                    // izvrsi zamjenu genetskog materijala
                    node.SubFunctionTree[r] = Swap(node.SubFunctionTree[r], c2);
                    break;//prekini petlju jer je ukrstanje napravljeno
                }

                // Udju u potomke potomka
                node = child;
            }

            // Na kraju poravnati dubinu na ogranicenu ako je doslo do povecaja dubine
            Trim(c1, gpParameters.maxCossoverLevel);
            Trim(c2, gpParameters.maxCossoverLevel);
        }
예제 #3
0
        /// <summary>
        /// Evaluation of chromosome
        /// </summary>
        /// <param name="c"></param>
        private void EvaluateChromosome(GPChromosome c)
        {
            c.Fitness = 0;
            List <int> lst = new List <int>();

            FunctionTree.ToListExpression(lst, c.Root);
            gpParameters.GPFitness.Evaluate(lst, gpFunctionSet, gpTerminalSet, c);
        }
예제 #4
0
 public static void ToListExpression(List <int> lstExpr, FunctionTree node)
 {
     //If subFunctTree is not null
     if (node.SubFunctionTree != null)
     {
         Debug.Assert(node.SubFunctionTree.Count != 0);
         // pretraži sve čvorove
         for (int i = 0; i < node.SubFunctionTree.Count; i++)
         {
             ToListExpression(lstExpr, node.SubFunctionTree[i]);
         }
     }
     lstExpr.Add(node.NodeValue);
 }
예제 #5
0
        private void GenerateChromosome(FunctionTree treeNode, int level)
        {
            if (level <= 0)
            {
                GenerateGene(treeNode, false);
                treeNode.SubFunctionTree = null;
            }
            else
            {
                //Ako nije maximalni novo onda treba postupiti shodno metodi inicijalizacije
                if (gpParameters.einitializationMethod == EInitializationMethod.FullInitialization ||
                    gpParameters.einitializationMethod == EInitializationMethod.HalfHalfInitialization)
                {
                    GenerateGene(treeNode, true);
                }
                else//A ako je u pitanju rastuca slucajno generisi cvor
                {
                    GenerateGene(treeNode);
                }
            }

            // Kada se je generirao Cvor (GEN) gornji kod, tada se trea generirati i
            // potomci toga Gena. Odnosno generiraj onoliko potomaka koliko funkcija ima argumenata
            if (treeNode.NodeValue > 1999)
            {
                //Number of aritry of node function
                int numAritry = gpFunctionSet.functions[treeNode.NodeValue - 2000].Aritry;

                //Formiraj onoliko potomaka koliko ima argumenata
                treeNode.SubFunctionTree = new List <FunctionTree>(numAritry);

                //Svaki novonastali potomak inicijaliziraj i generiraj
                for (int i = 0; i < numAritry; i++)
                {
                    // Formiraj potomak
                    FunctionTree child = new FunctionTree();

                    //Generiraj ga s tim da se nivo smanji za jedan
                    GenerateChromosome(child, level - 1);

                    // Kad se generira pridruzi potomke njgovom rodtelju
                    treeNode.SubFunctionTree.Add(child);
                }
            }
        }
예제 #6
0
        public object Clone()
        {
            FunctionTree clone = new FunctionTree();

            // clone node2 value
            clone.NodeValue = this.NodeValue;

            // clone its subtrees
            if (this.SubFunctionTree != null)
            {
                clone.SubFunctionTree = new List <FunctionTree>();
                // clone each child gene
                for (int i = 0; i < this.SubFunctionTree.Count; i++)
                {
                    FunctionTree cl = (FunctionTree)this.SubFunctionTree[i].Clone();
                    clone.SubFunctionTree.Add(cl);
                }
            }
            return(clone);
        }
예제 #7
0
        private void GenerateGene(FunctionTree gPGenNode, bool isFunction)
        {
            //Ako je broj terminala veći od 1000
            if (gpFunctionSet.terminals.Count > 999)
            {
                throw new Exception("Maximum number of terminals must be less than 999");
            }

            // Brojevi veci od 2000 oznacavat ce funkcije
            if (isFunction)
            {
                short f = (short)rand.Next(gpFunctionSet.functions.Count);
                gPGenNode.NodeValue = (short)(2000 + f);
            }

            //Brojevi od 1000-2000 oznacavat ce slobodne koeficijente i ulazne parametre
            else
            {
                //Slucajno biramo jedan od terminala
                short r = (short)rand.Next(gpFunctionSet.terminals.Count);
                gPGenNode.NodeValue = (short)(1000 + r);
            }
        }
예제 #8
0
        private FunctionTree Swap(FunctionTree c1, FunctionTree c2)
        {
            //privremena varijabla
            FunctionTree node2 = c2;

            while (true)
            {
                if (node2.SubFunctionTree == null)
                {
                    // zamjena cvorova
                    FunctionTree tempNode = c2;
                    c2 = c1;
                    return(tempNode);
                }
                // slucajno izabiremo potomak od node2-a
                int r = rand.Next(node2.SubFunctionTree.Count);

                //pohranjujemo potomak u varijablu child i sad od njega poslije trazimo tacku ukrstanja
                FunctionTree child = node2.SubFunctionTree[r];

                // swap the random node2, if it is an end node2 or
                // random generator "selected" this node2
                //Ako child nema potomaka tada tj ako je terminal tada je to tacka zamjene
                if ((child.SubFunctionTree == null) || (rand.Next(gpParameters.maxCossoverLevel) == 0 /*(int)(gpParameters.maxCossoverLevel / 2)*/))
                {
                    // zamjena cvorova
                    FunctionTree tempNode = node2.SubFunctionTree[r];
                    node2.SubFunctionTree[r] = c1;
                    return(tempNode);
                }

                //Ako child ima potomke tada se vracamo na pocetak i
                //ponovo slucajno biramo potomak sad od child-a
                node2 = child;
            }
        }
예제 #9
0
 public FunctionTree(FunctionTree node)
 {
     NodeValue       = node.NodeValue;
     SubFunctionTree = node.SubFunctionTree;
 }
예제 #10
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 public GPChromosome(GPChromosome source)
 {
     //Helper for cloning
     Root    = (FunctionTree)source.Root.Clone();
     fitness = source.Fitness;
 }
예제 #11
0
        public void PermutateChromosome(FunctionTree c)
        {
            // current node
            FunctionTree node = c;

            while (true)
            {
                if (node.SubFunctionTree == null)
                {
                    break;
                }
                //Ovdje pocinjemo proces mutacije. Slucajno generisemo tačku mutacije. Odnosno generiramo slucajnog
                // potomka. Koji ce mutirati ili ce mutirati njegov potomak
                int r     = rand.Next(node.SubFunctionTree.Count + 1);
                int count = node.SubFunctionTree.Count;
                //Ako smo generirali broj koji je isti kao i broj potomaka argumenata funkcija tada je odluka da taj cvor mutira
                //Ovo mi je malo bezvez nacin odluke koji ce cvor mutirati jer je u glavnom broj argumenata 2 tako da vec prvi cvorovi
                // najvjerojatnije da ce mutirati
                if (r == count)
                {
                    // Kada smo odabrali da ce doticni cvor da permutira
                    // generiramo slucajnu permutaciju na osnovu broja argumenata
                    int aritry = count;

                    //Ako je aritry == 1 onda nema smisla praviti permutaciju
                    if (aritry <= 1)
                    {
                        continue;
                    }
                    //Ako je Aritry == 2 tada imamo samo jednu permutaciju pa
                    // je definšemo na sljedeci nacin
                    else if (aritry == 2)
                    {
                        FunctionTree temp = null;
                        temp = node.SubFunctionTree[0];
                        node.SubFunctionTree[0] = node.SubFunctionTree[1];
                        node.SubFunctionTree[1] = temp;
                    }
                    else
                    {
                        for (int ii = 0; ii < aritry; ii++)
                        {
                            FunctionTree temp       = null;
                            int          temIndex   = rand.Next(aritry);
                            int          tempIndex2 = rand.Next(aritry);
                            if (temIndex != tempIndex2)
                            {
                                temp = node.SubFunctionTree[temIndex];
                                node.SubFunctionTree[temIndex]   = node.SubFunctionTree[tempIndex2];
                                node.SubFunctionTree[tempIndex2] = temp;
                            }
                        }
                    }

                    break;//Kada se dogodi mutacija tada for petlja nema vise sta da vrti
                }

                // prelazimo na novi nivo
                node = node.SubFunctionTree[r];
            }
        }
예제 #12
0
        public void MutateChromosome(FunctionTree c)
        {
            //Refeentni nivo
            int currentLevel = 0;
            //Maximalni nivo mutacija. -1 ide zbog brojanja od nule
            int maxLevel = gpParameters.maxMutationLevel - 1;
            // current node
            FunctionTree node = c;

            while (true)
            {
                // Ako je node bez potomaka onda treba generiratido nivoa maximalnog za mutaciju
                if (node.SubFunctionTree == null)
                {
                    //Ako je tekuci nivo dostigao maximalni nivo mutacije formiraj Terminal
                    if (currentLevel >= maxLevel)
                    {
                        GenerateGene(node, false);
                    }

                    else //Ako je tekuci nivo manji od maximalnog onda generiraj dalje
                    {
                        GenerateChromosome(node, currentLevel - 1);
                    }
                    break;
                }

                //Ovdje pocinjemo proces mutacije. Slucajno generisemo tačku mutacije. Odnosno generiramo slucajnog
                // potomka. Koji ce mutirati ili ce mutirati njegov potomak. +1 znaci generiranje brojeva do vrijednosti Cout
                // ako je generirani broj == Count tada taj cvor mutira inace mutira njegov generirani potomak
                int r = rand.Next(node.SubFunctionTree.Count + 1);


                //Ako smo generirali broj koji je isti kao i broj potomaka argumenata funkcija tada je odluka da taj cvor mutira
                //Ovo mi je malo bezvez nacin odluke koji ce cvor mutirati jer je u glavnom broj argumenata 2 tako da vec prvi cvorovi
                // najvjerojatnije da ce mutirati
                if (r == node.SubFunctionTree.Count)
                {
                    // Kada smo odabrali da ce doticni cvor da mutira
                    // ponovo ga regegeneriramo.
                    if (currentLevel >= maxLevel)//Ako je level veci ili jedna maximalnom levelu tada moramo generirati terminal
                    {
                        GenerateGene(node, false);
                    }
                    else
                    {
                        GenerateGene(node);
                    }

                    // Ako smo regenerirani cvor postao terminal tada njegovi potomci
                    // trebaju biti odbacenu
                    if (node.NodeValue < 2000)// || currentLevel >= maxLevel)
                    {
                        node.SubFunctionTree = null;
                    }

                    else//Ako je novogenerirani (mutirani cvor ) funkcija tada dalje regeneriramo hromosom
                    {
                        // ako mutirani cvor ne posjeduje potomke
                        // potrebno ih je formirati
                        int count = 0;
                        if (node.SubFunctionTree == null)
                        {
                            //I to onoliko koliko ima argumanata mutirani cvor
                            count = gpFunctionSet.functions[node.NodeValue - 2000].Aritry;
                            node.SubFunctionTree = new List <FunctionTree>(count);
                        }
                        else
                        {
                            count = gpFunctionSet.functions[node.NodeValue - 2000].Aritry;
                            //Debug.Assert(count == gpFunctionSet.functions[node.NodeValue.IndexValue - 2000].Aritry);
                        }
                        // Sada uskladjujemo potomke sa brojem argumenata
                        //funkcije koje se formirala nakon mutacije
                        //To znaci da akomutirani cvor ima isti broj argumenata kao i prije mutacije
                        // tu ne radimo nista ostavljamo ga kakav jeste
                        //A ako je taj broj razlicit potrebno je to usladiti
                        if (node.SubFunctionTree.Count != count)
                        {
                            //Pa ako je broj argumenata veci tada odstranjujemo visak
                            if (node.SubFunctionTree.Count > count)
                            {
                                // remove extra children
                                node.SubFunctionTree.RemoveRange(count, node.SubFunctionTree.Count - count);
                            }
                            else//A ako je manji dodajemo
                            {
                                // add missing children
                                for (int i = node.SubFunctionTree.Count; i < count; i++)
                                {
                                    // create new child
                                    FunctionTree child = new FunctionTree();
                                    GenerateChromosome(child, currentLevel - 1);
                                    // add the new child
                                    node.SubFunctionTree.Add(child);
                                }
                            }
                        }
                    }
                    break;//Kada se dogodi mutacija tada for petlja nema vise sta da vrti
                }

                // Ako se nije desila mutacija na tekucem novou tada nivo pomjeramo za jedan vise i ponavljamo petlju
                node = node.SubFunctionTree[r];
                currentLevel++;
            }
        }
예제 #13
0
 private void GenerateGene(FunctionTree gPGenNode)
 {
     // potrebno je dati više vjerojatnost da se generiše funkcija u odnosu na terminale
     GenerateGene(gPGenNode, (rand.Next(4) != 3));
 }