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); } } }
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); }
/// <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); }
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); }
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); } } }
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); }
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); } }
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; } }
public FunctionTree(FunctionTree node) { NodeValue = node.NodeValue; SubFunctionTree = node.SubFunctionTree; }
/// <summary> /// Copy constructor /// </summary> public GPChromosome(GPChromosome source) { //Helper for cloning Root = (FunctionTree)source.Root.Clone(); fitness = source.Fitness; }
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]; } }
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++; } }
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)); }