public void Merge( Population pop1, Population pop2, ProblemDefinition problem) { IndList.Clear(); for (int i = 0; i < pop1.IndList.Count; i++) { IndList.Add( new Individual(pop1.IndList[i], problem)); } for (int i = 0; i < pop2.IndList.Count; i++) { IndList.Add(new Individual(pop2.IndList[i], problem)); } }
///* Function to display the current population for the subsequent generation */ public void PlotPopulation(Population pop, ProblemDefinition problem, int genNo = 0, List<Individual> best = null) { if (!Use3D) //2D { var xr = new double[problem.PopulationSize]; var yr = new double[problem.PopulationSize]; for (int x = 0; x < problem.PopulationSize; x++) { xr[x] = pop.IndList[x].Obj[GnuplotObjective1]; yr[x] = pop.IndList[x].Obj[GnuplotObjective2]; } if (best != null) { GnuPlot.HoldOn(); } GnuPlot.Plot(xr, yr, $"title 'Generation #{genNo} of {problem.MaxGeneration}' with points pointtype 8 lc rgb 'blue'"); if (best != null) { var x = new double[best.Count]; var y = new double[best.Count]; for (int i = 0; i < best.Count; i++) { x[i] = best[i].Obj[GnuplotObjective1]; y[i] = best[i].Obj[GnuplotObjective2]; } GnuPlot.Plot(x, y, $"title 'best ({best.First().TotalResult})' with points pointtype 6 lc rgb 'red'"); } GnuPlot.Set($"xlabel \"obj[{GnuplotObjective1 }]\""); GnuPlot.Set($"ylabel \"obj[{GnuplotObjective2 }]\""); } else //3D { var rank1Count = pop.IndList.Count(x => x.Rank == 1); var rankOtherCount = pop.IndList.Count(x => x.Rank != 1); if (rank1Count > 0) { var xr = new double[rank1Count]; var yr = new double[rank1Count]; var zr = new double[rank1Count]; int index = 0; foreach (var ind in pop.IndList.Where(x => x.Rank == 1)) { xr[index] = ind.Obj[GnuplotObjective1]; yr[index] = ind.Obj[GnuplotObjective2]; zr[index] = ind.Obj[GnuplotObjective3]; index++; } if (best != null || rankOtherCount > 0) { GnuPlot.HoldOn(); } GnuPlot.SPlot(xr, yr, zr, $"title 'Rank 1 individuals' with points pointtype 8 lc rgb 'red'"); } if (rankOtherCount > 0) { var xr = new double[rankOtherCount]; var yr = new double[rankOtherCount]; var zr = new double[rankOtherCount]; int index = 0; foreach (var ind in pop.IndList.Where(x => x.Rank != 1)) { xr[index] = ind.Obj[GnuplotObjective1]; yr[index] = ind.Obj[GnuplotObjective2]; zr[index] = ind.Obj[GnuplotObjective3]; index++; } GnuPlot.SPlot(xr, yr, zr, $"title 'Rank 2-{pop.IndList.Max(x=>x.Rank)} individuals' with points pointtype 8 lc rgb 'blue'"); } if (best != null) { var x = new double[best.Count]; var y = new double[best.Count]; var z = new double[best.Count]; for (int i = 0; i < best.Count; i++) { x[i] = best[i].Obj[GnuplotObjective1]; y[i] = best[i].Obj[GnuplotObjective2]; z[i] = best[i].Obj[GnuplotObjective3]; } GnuPlot.SPlot(x, y, z, $"title 'best ({best.First().TotalResult})' with points pointtype 6 lc rgb 'green'"); } GnuPlot.Set($"title 'Generation #{genNo} of {problem.MaxGeneration}'"); GnuPlot.Set($"xlabel \"obj[{GnuplotObjective1}]\""); GnuPlot.Set($"ylabel \"obj[{GnuplotObjective2}]\""); GnuPlot.Set($"zlabel \"obj[{GnuplotObjective3}]\""); } }
/* Randomized quick sort routine to sort a population based on crowding distance */ static void quicksort_dist(Population pop, int[] dist, int frontSize, Randomization randomizationObj) { q_sort_dist(pop, dist, 0, frontSize - 1, randomizationObj); }
/* Randomized quick sort routine to sort a population based on a particular objective chosen */ static void quicksort_front_obj(Population pop, int objcount, int[] objArray, int objArraySize, Randomization randomizationObj) { q_sort_front_obj(pop, objcount, objArray, 0, objArraySize - 1, randomizationObj); }
/* Routine to perform non-dominated sorting */ static void fill_nondominated_sort(Population mixedPop, Population newPop, ProblemDefinition problemObj, Randomization randomizationObj) { int flag; int i, j; int end; int frontSize; int archieveSize; int rank = 1; Lists pool; Lists elite; Lists temp1, temp2; pool = new Lists(); elite = new Lists(); frontSize = 0; archieveSize = 0; pool.index = -1; pool.parent = null; pool.child = null; elite.index = -1; elite.parent = null; elite.child = null; temp1 = pool; for (i = 0; i < 2 * problemObj.PopulationSize; i++) { Insert(temp1, i); temp1 = temp1.child; } i = 0; do { temp1 = pool.child; Insert(elite, temp1.index); frontSize = 1; temp2 = elite.child; temp1 = Delete(temp1); temp1 = temp1.child; do { temp2 = elite.child; if (temp1 == null) { break; } do { end = 0; flag = CheckDominance(mixedPop.IndList[temp1.index], mixedPop.IndList[temp2.index], problemObj); if (flag == 1) { Insert(pool, temp2.index); temp2 = Delete(temp2); frontSize--; temp2 = temp2.child; } if (flag == 0) { temp2 = temp2.child; } if (flag == -1) { end = 1; } } while (end != 1 && temp2 != null); if (flag == 0 || flag == 1) { Insert(elite, temp1.index); frontSize++; temp1 = Delete(temp1); } temp1 = temp1.child; } while (temp1 != null); temp2 = elite.child; j = i; if (archieveSize + frontSize <= problemObj.PopulationSize) { do { newPop.IndList[i].Copy(mixedPop.IndList[temp2.index], problemObj); //CopyIndividual(mixedPop.IndList[temp2.index], newPop.IndList[i]); newPop.IndList[i].Rank = rank; archieveSize += 1; temp2 = temp2.child; i += 1; } while (temp2 != null); assign_crowding_distance_indices(newPop, j, i - 1, problemObj, randomizationObj); rank += 1; } else { crowding_fill(mixedPop, newPop, i, frontSize, elite, problemObj, randomizationObj); archieveSize = problemObj.PopulationSize; for (j = i; j < problemObj.PopulationSize; j++) { newPop.IndList[j].Rank = rank; } } temp2 = elite.child; do { temp2 = Delete(temp2); temp2 = temp2.child; } while (elite.child != null); } while (archieveSize < problemObj.PopulationSize); }
/* Function to perform mutation in a population */ static void MutatePopulation(Population pop, ProblemDefinition problemObj, Randomization randomizationObj) { int i; for (i = 0; i < problemObj.PopulationSize; i++) { MutateIndividual(pop.IndList[i], problemObj, randomizationObj); } }
/* Function to assign rank and crowding distance to a population of size pop_size*/ static void assign_rank_and_crowding_distance(Population newPopulation, ProblemDefinition problemObj, Randomization randomizationObj) { int flag; int i; int end; int frontSize; int rank = 1; Lists orig; Lists cur; Lists temp1, temp2; orig = new Lists(); cur = new Lists(); orig.index = -1; orig.parent = null; orig.child = null; cur.index = -1; cur.parent = null; cur.child = null; temp1 = orig; for (i = 0; i < problemObj.PopulationSize; i++) { Insert(temp1, i); temp1 = temp1.child; } do { if (orig.child != null && orig.child.child == null) { newPopulation.IndList[orig.child.index].Rank = rank; newPopulation.IndList[orig.child.index].CrowdDist = problemObj.Inf; break; } temp1 = orig.child; Insert(cur, temp1.index); frontSize = 1; temp2 = cur.child; temp1 = Delete(temp1); temp1 = temp1.child; do { temp2 = cur.child; do { end = 0; flag = CheckDominance(newPopulation.IndList[temp1.index], newPopulation.IndList[temp2.index], problemObj); if (flag == 1) { Insert(orig, temp2.index); temp2 = Delete(temp2); frontSize--; temp2 = temp2.child; } if (flag == 0) { temp2 = temp2.child; } if (flag == -1) { end = 1; } } while (end != 1 && temp2 != null); if (flag == 0 || flag == 1) { Insert(cur, temp1.index); frontSize++; temp1 = Delete(temp1); } temp1 = temp1.child; } while (temp1 != null); temp2 = cur.child; do { newPopulation.IndList[temp2.index].Rank = rank; temp2 = temp2.child; } while (temp2 != null); assign_crowding_distance_list(newPopulation, cur.child, frontSize, problemObj, randomizationObj); temp2 = cur.child; do { temp2 = Delete(temp2); temp2 = temp2.child; } while (cur.child != null); rank += 1; } while (orig.child != null); }
/* Routine to fill a population with individuals in the decreasing order of crowding distance */ static void crowding_fill(Population mixedPop, Population newPop, int count, int frontSize, Lists elite, ProblemDefinition ProblemObj, Randomization RandomizationObj) { int[] dist; Lists temp; int i, j; assign_crowding_distance_list(mixedPop, elite.child, frontSize, ProblemObj, RandomizationObj); dist = new int[frontSize]; temp = elite.child; for (j = 0; j < frontSize; j++) { dist[j] = temp.index; temp = temp.child; } quicksort_dist(mixedPop, dist, frontSize, RandomizationObj); for (i = count, j = frontSize - 1; i < ProblemObj.PopulationSize; i++, j--) { newPop.IndList[i].Copy(mixedPop.IndList[dist[j]], ProblemObj); //CopyIndividual(mixedPop.IndList[dist[j]], newPop.IndList[i]); //newPop.IndList[i] = new Individual(mixedPop.IndList[dist[j]], ProblemObj); } }
/* Routine to compute crowding distance based on objective function values when the population in in the form of an array */ static void assign_crowding_distance_indices(Population pop, int c1, int c2, ProblemDefinition problemObj, Randomization randomizationObj) { int[][] objArray; int[] dist; int i, j; int frontSize; frontSize = c2 - c1 + 1; if (frontSize == 1) { pop.IndList[c1].CrowdDist = problemObj.Inf; return; } if (frontSize == 2) { pop.IndList[c1].CrowdDist = problemObj.Inf; pop.IndList[c2].CrowdDist = problemObj.Inf; return; } dist = new int[frontSize]; objArray = new int[problemObj.ObjectiveCount][]; //obj_array = (int**)malloc(ProblemObj.ObjectiveCount * sizeof(int*)); for (i = 0; i < problemObj.ObjectiveCount; i++) { objArray[i] = new int[frontSize]; } for (j = 0; j < frontSize; j++) { dist[j] = c1++; } assign_crowding_distance(pop, dist, objArray, frontSize, problemObj, randomizationObj); }
/* Routine to compute crowding distance based on ojbective function values when the population in in the form of a list */ static void assign_crowding_distance_list(Population pop, Lists lst, int frontSize, ProblemDefinition problemObj, Randomization randomizationObj) { int[][] objArray; int[] dist; int i, j; Lists temp; temp = lst; if (frontSize == 1) { pop.IndList[lst.index].CrowdDist = problemObj.Inf; return; } if (frontSize == 2) { pop.IndList[lst.index].CrowdDist = problemObj.Inf; pop.IndList[lst.child.index].CrowdDist = problemObj.Inf; return; } dist = new int[frontSize]; objArray = new int[problemObj.ObjectiveCount][]; //obj_array = (int**)malloc(ProblemObj.ObjectiveCount * sizeof(int*)); for (i = 0; i < problemObj.ObjectiveCount; i++) { objArray[i] = new int[frontSize]; } for (j = 0; j < frontSize; j++) { dist[j] = temp.index; temp = temp.child; } assign_crowding_distance(pop, dist, objArray, frontSize, problemObj, randomizationObj); }
/* Routine to compute crowding distances */ static void assign_crowding_distance(Population pop, int[] dist, int[][] objArray, int frontSize, ProblemDefinition problemObj, Randomization randomizationObj) { int i, j; for (i = 0; i < problemObj.ObjectiveCount; i++) { for (j = 0; j < frontSize; j++) { objArray[i][j] = dist[j]; } quicksort_front_obj(pop, i, objArray[i], frontSize, randomizationObj); } for (j = 0; j < frontSize; j++) { pop.IndList[dist[j]].CrowdDist = 0.0; } for (i = 0; i < problemObj.ObjectiveCount; i++) { pop.IndList[objArray[i][0]].CrowdDist = problemObj.Inf; } for (i = 0; i < problemObj.ObjectiveCount; i++) { for (j = 1; j < frontSize - 1; j++) { if (pop.IndList[objArray[i][j]].CrowdDist != problemObj.Inf) { if (pop.IndList[objArray[i][frontSize - 1]].Obj[i] == pop.IndList[objArray[i][0]].Obj[i]) { pop.IndList[objArray[i][j]].CrowdDist += 0.0; } else { pop.IndList[objArray[i][j]].CrowdDist += (pop.IndList[objArray[i][j + 1]].Obj[i] - pop.IndList[objArray[i][j - 1]].Obj[i]) / (pop.IndList[objArray[i][frontSize - 1]].Obj[i] - pop.IndList[objArray[i][0]].Obj[i]); } } } } for (j = 0; j < frontSize; j++) { if (pop.IndList[dist[j]].CrowdDist != problemObj.Inf) { pop.IndList[dist[j]].CrowdDist = pop.IndList[dist[j]].CrowdDist / problemObj.ObjectiveCount; } } }
private void CreatePopulationObject() { ParentPopulation = new Population(ProblemObj.PopulationSize, ProblemObj.RealVariableCount, ProblemObj.BinaryVariableCount, ProblemObj.MaxBitCount, ProblemObj.ObjectiveCount, ProblemObj.ConstraintCount); ChildPopulation = new Population(ProblemObj.PopulationSize, ProblemObj.RealVariableCount, ProblemObj.BinaryVariableCount, ProblemObj.MaxBitCount, ProblemObj.ObjectiveCount, ProblemObj.ConstraintCount); MixedPopulation = new Population(ProblemObj.PopulationSize * 2, ProblemObj.RealVariableCount, ProblemObj.BinaryVariableCount, ProblemObj.MaxBitCount, ProblemObj.ObjectiveCount, ProblemObj.ConstraintCount); }
/* Routine for Tournament Selection, it creates a newPopulation from oldPopulation by performing Tournament Selection and the Crossover */ static void Selection(Population oldPopulation, Population newPopulation, ProblemDefinition problemObj, Randomization randomizationObj) { int[] a1, a2; //todo: optmizasyon int temp; int i; int rand; Individual parent1, parent2; a1 = new int[problemObj.PopulationSize]; a2 = new int[problemObj.PopulationSize]; for (i = 0; i < problemObj.PopulationSize; i++) { a1[i] = a2[i] = i; } for (i = 0; i < problemObj.PopulationSize; i++) { rand = randomizationObj.RandomInteger(i, problemObj.PopulationSize - 1); temp = a1[rand]; a1[rand] = a1[i]; a1[i] = temp; rand = randomizationObj.RandomInteger(i, problemObj.PopulationSize - 1); temp = a2[rand]; a2[rand] = a2[i]; a2[i] = temp; } for (i = 0; i < problemObj.PopulationSize; i += 4) { parent1 = Tournament(oldPopulation.IndList[a1[i]], oldPopulation.IndList[a1[i + 1]], problemObj, randomizationObj); parent2 = Tournament(oldPopulation.IndList[a1[i + 2]], oldPopulation.IndList[a1[i + 3]], problemObj, randomizationObj); Crossover(parent1, parent2, newPopulation.IndList[i], newPopulation.IndList[i + 1], problemObj, randomizationObj); parent1 = Tournament(oldPopulation.IndList[a2[i]], oldPopulation.IndList[a2[i + 1]], problemObj, randomizationObj); parent2 = Tournament(oldPopulation.IndList[a2[i + 2]], oldPopulation.IndList[a2[i + 3]], problemObj, randomizationObj); Crossover(parent1, parent2, newPopulation.IndList[i + 2], newPopulation.IndList[i + 3], problemObj, randomizationObj); } }
/* Actual implementation of the randomized quick sort used to sort a population based on a particular objective chosen */ static void q_sort_front_obj(Population pop, int objcount, int[] objArray, int left, int right, Randomization randomizationObj) { int index; int temp; int i, j; double pivot; if (left < right) { index = randomizationObj.RandomInteger(left, right); temp = objArray[right]; objArray[right] = objArray[index]; objArray[index] = temp; pivot = pop.IndList[objArray[right]].Obj[objcount]; i = left - 1; for (j = left; j < right; j++) { if (pop.IndList[objArray[j]].Obj[objcount] <= pivot) { i += 1; temp = objArray[j]; objArray[j] = objArray[i]; objArray[i] = temp; } } index = i + 1; temp = objArray[index]; objArray[index] = objArray[right]; objArray[right] = temp; q_sort_front_obj(pop, objcount, objArray, left, index - 1, randomizationObj); q_sort_front_obj(pop, objcount, objArray, index + 1, right, randomizationObj); } }
/* Actual implementation of the randomized quick sort used to sort a population based on crowding distance */ static void q_sort_dist(Population pop, int[] dist, int left, int right, Randomization randomizationObj) { int index; int temp; int i, j; double pivot; if (left < right) { index = randomizationObj.RandomInteger(left, right); temp = dist[right]; dist[right] = dist[index]; dist[index] = temp; pivot = pop.IndList[dist[right]].CrowdDist; i = left - 1; for (j = left; j < right; j++) { if (pop.IndList[dist[j]].CrowdDist <= pivot) { i += 1; temp = dist[j]; dist[j] = dist[i]; dist[i] = temp; } } index = i + 1; temp = dist[index]; dist[index] = dist[right]; dist[right] = temp; q_sort_dist(pop, dist, left, index - 1, randomizationObj); q_sort_dist(pop, dist, index + 1, right, randomizationObj); } }