public void Initialize(ProblemDefinition problem, Randomization randomObj) { for (int i = 0; i < IndList.Count; i++) { IndList[i].Initialize(problem, randomObj); } }
/* 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); }
/* 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); } }
/* Function to cross two individuals */ static void Crossover(Individual parent1, Individual parent2, Individual child1, Individual child2, ProblemDefinition problemObj, Randomization randomizationObj) { if (problemObj.RealVariableCount != 0) { RealCrossover(parent1, parent2, child1, child2, problemObj, randomizationObj); } if (problemObj.BinaryVariableCount != 0) { BinaryCrossover(parent1, parent2, child1, child2, problemObj, randomizationObj); } }
/* Routine for binary mutation of an individual */ static void BinaryMutate(Individual ind, ProblemDefinition problemObj, Randomization randomizationObj) { int j, k; double prob; for (j = 0; j < problemObj.BinaryVariableCount; j++) { for (k = 0; k < problemObj.Nbits[j]; k++) { prob = randomizationObj.RandomPercent(); if (prob <= problemObj.BinaryMutationProbability) { if (ind.Gene[j][k] == 0) { ind.Gene[j][k] = 1; } else { ind.Gene[j][k] = 0; } problemObj.BinaryMutationCount += 1; } } } }
/* 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); } }
/* 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); }
/* 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; } } }
/* 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 for binary Tournament */ static Individual Tournament(Individual ind1, Individual ind2, ProblemDefinition problemObj, Randomization randomizationObj) { var flag = CheckDominance(ind1, ind2, problemObj); if (flag == 1) { return ind1; } if (flag == -1) { return ind2; } if (ind1.CrowdDist > ind2.CrowdDist) { return ind1; } if (ind2.CrowdDist > ind1.CrowdDist) { return ind2; } if (randomizationObj.RandomPercent() <= 0.5) { return ind1; } else { return ind2; } }
public UCTProblem(double dSeed, int nPopulation, int nMaxGeneration, int nObjective, int nConstraint, bool useBinary, double crossProbability, double mutateProbability, bool usePlot = false, DisabledCollisions disableOptions = DisabledCollisions.None) { CurrentGeneration = 0; Seed = dSeed; if (Seed <= 0.0 || Seed >= 1.0) { Console.WriteLine("\n Entered seed value is wrong, seed value must be in (0,1) \n"); Seed = 0.75; } UsePlot = usePlot; var title = RandomTitle.GetRandomTitle(); ProblemObj = new ProblemDefinition(title) { PopulationSize = nPopulation, MaxGeneration = nMaxGeneration, ObjectiveCount = nObjective, ConstraintCount = nConstraint, BinaryVariableCount = 0, RealVariableCount = 0, DisabledCollisions = disableOptions }; ProblemObj.TeacherList.Add("ASSISTANT"); ReadCourseList(); if (useBinary) { ProblemObj.BinaryVariableCount = ProblemObj.CourseList.Count; PrepareBinaryLimits(); ProblemObj.BinaryCrossoverProbability = crossProbability; if (ProblemObj.BinaryCrossoverProbability < 0.0 || ProblemObj.BinaryCrossoverProbability > 1.0) { ProblemObj.BinaryCrossoverProbability = 0.75; } ProblemObj.BinaryMutationProbability = mutateProbability; if (ProblemObj.BinaryMutationProbability < 0.0 || ProblemObj.BinaryMutationProbability > 1.0) { ProblemObj.BinaryMutationProbability = 0.0232558; } } else { ProblemObj.BinaryVariableCount = ProblemObj.CourseList.Count; ReadRealValues(); ProblemObj.BinaryCrossoverProbability = crossProbability; if (ProblemObj.BinaryCrossoverProbability < 0.0 || ProblemObj.BinaryCrossoverProbability > 1.0) { ProblemObj.BinaryCrossoverProbability = 0.75; } ProblemObj.BinaryMutationProbability = mutateProbability; if (ProblemObj.BinaryMutationProbability < 0.0 || ProblemObj.BinaryMutationProbability > 1.0) { ProblemObj.BinaryMutationProbability = 0.0232558; } } WriteStartParams(); RandomizationObj = new Randomization(dSeed); RandomizationObj.Randomize(); _displayObj = new Display(); InitDisplay(true, true, new[] { 0, 1, 2 }); ReadFacultyCourses(); ReadLab(); ReadMeeting(); ReadPreq(); CreatePopulationObject(); }
/* 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); } }
/* Routine for real polynomial mutation of an individual */ static void RealMutate(Individual ind, ProblemDefinition problemObj, Randomization randomizationObj) { int j; double rnd, delta1, delta2, mutPow, deltaq; double y, yl, yu, val, xy; for (j = 0; j < problemObj.RealVariableCount; j++) { if (randomizationObj.RandomPercent() <= problemObj.RealMutationProbability) { y = ind.Xreal[j]; yl = problemObj.MinRealvar[j]; yu = problemObj.MaxRealvar[j]; delta1 = (y - yl) / (yu - yl); delta2 = (yu - y) / (yu - yl); rnd = randomizationObj.RandomPercent(); mutPow = 1.0 / (problemObj.MutationDistributionIndex + 1.0); if (rnd <= 0.5) { xy = 1.0 - delta1; val = 2.0 * rnd + (1.0 - 2.0 * rnd) * Math.Pow(xy, problemObj.MutationDistributionIndex + 1.0); deltaq = Math.Pow(val, mutPow) - 1.0; } else { xy = 1.0 - delta2; val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * Math.Pow(xy, problemObj.MutationDistributionIndex + 1.0); deltaq = 1.0 - Math.Pow(val, mutPow); } y = y + deltaq * (yu - yl); if (y < yl) y = yl; if (y > yu) y = yu; ind.Xreal[j] = y; problemObj.RealMutationCount += 1; } } }
/* Routine for real variable SBX Crossover */ static void RealCrossover(Individual parent1, Individual parent2, Individual child1, Individual child2, ProblemDefinition problemObj, Randomization randomizationObj) { int i; double rand; double y1, y2, yl, yu; double c1, c2; double alpha, beta, betaq; if (randomizationObj.RandomPercent() <= problemObj.RealCrossoverProbability) { problemObj.RealCrossoverCount++; for (i = 0; i < problemObj.RealVariableCount; i++) { if (randomizationObj.RandomPercent() <= 0.5) { if (Math.Abs(parent1.Xreal[i] - parent2.Xreal[i]) > problemObj.Eps) { if (parent1.Xreal[i] < parent2.Xreal[i]) { y1 = parent1.Xreal[i]; y2 = parent2.Xreal[i]; } else { y1 = parent2.Xreal[i]; y2 = parent1.Xreal[i]; } yl = problemObj.MinRealvar[i]; yu = problemObj.MaxRealvar[i]; rand = randomizationObj.RandomPercent(); beta = 1.0 + 2.0 * (y1 - yl) / (y2 - y1); alpha = 2.0 - Math.Pow(beta, -(problemObj.CrossoverDistributionIndex + 1.0)); if (rand <= 1.0 / alpha) { betaq = Math.Pow(rand * alpha, 1.0 / (problemObj.CrossoverDistributionIndex + 1.0)); } else { betaq = Math.Pow(1.0 / (2.0 - rand * alpha), 1.0 / (problemObj.CrossoverDistributionIndex + 1.0)); } c1 = 0.5 * (y1 + y2 - betaq * (y2 - y1)); beta = 1.0 + 2.0 * (yu - y2) / (y2 - y1); alpha = 2.0 - Math.Pow(beta, -(problemObj.CrossoverDistributionIndex + 1.0)); if (rand <= 1.0 / alpha) { betaq = Math.Pow(rand * alpha, 1.0 / (problemObj.CrossoverDistributionIndex + 1.0)); } else { betaq = Math.Pow(1.0 / (2.0 - rand * alpha), 1.0 / (problemObj.CrossoverDistributionIndex + 1.0)); } c2 = 0.5 * (y1 + y2 + betaq * (y2 - y1)); if (c1 < yl) c1 = yl; if (c2 < yl) c2 = yl; if (c1 > yu) c1 = yu; if (c2 > yu) c2 = yu; if (randomizationObj.RandomPercent() <= 0.5) { child1.Xreal[i] = c2; child2.Xreal[i] = c1; } else { child1.Xreal[i] = c1; child2.Xreal[i] = c2; } } else { child1.Xreal[i] = parent1.Xreal[i]; child2.Xreal[i] = parent2.Xreal[i]; } } else { child1.Xreal[i] = parent1.Xreal[i]; child2.Xreal[i] = parent2.Xreal[i]; } } } else { for (i = 0; i < problemObj.RealVariableCount; i++) { child1.Xreal[i] = parent1.Xreal[i]; child2.Xreal[i] = parent2.Xreal[i]; } } }
/* Function to perform mutation of an individual */ static void MutateIndividual(Individual ind, ProblemDefinition problemObj, Randomization randomizationObj) { if (problemObj.RealVariableCount != 0) { RealMutate(ind, problemObj, randomizationObj); } if (problemObj.BinaryVariableCount != 0) { BinaryMutate(ind, 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); }
/* 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); }
/* 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 for two point binary Crossover */ static void BinaryCrossover(Individual parent1, Individual parent2, Individual child1, Individual child2, ProblemDefinition problemObj, Randomization randomizationObj) { int i, j; double rand; int temp, site1, site2; for (i = 0; i < problemObj.BinaryVariableCount; i++) { rand = randomizationObj.RandomPercent(); if (rand <= problemObj.BinaryCrossoverProbability) { problemObj.BinaryCrossoverCount++; site1 = randomizationObj.RandomInteger(0, problemObj.Nbits[i] - 1); site2 = randomizationObj.RandomInteger(0, problemObj.Nbits[i] - 1); if (site1 > site2) { temp = site1; site1 = site2; site2 = temp; } for (j = 0; j < site1; j++) { child1.Gene[i][j] = parent1.Gene[i][j]; child2.Gene[i][j] = parent2.Gene[i][j]; } for (j = site1; j < site2; j++) { child1.Gene[i][j] = parent2.Gene[i][j]; child2.Gene[i][j] = parent1.Gene[i][j]; } for (j = site2; j < problemObj.Nbits[i]; j++) { child1.Gene[i][j] = parent1.Gene[i][j]; child2.Gene[i][j] = parent2.Gene[i][j]; } } else { for (j = 0; j < problemObj.Nbits[i]; j++) { child1.Gene[i][j] = parent1.Gene[i][j]; child2.Gene[i][j] = parent2.Gene[i][j]; } } } }
/* Function to initialize an individual randomly */ public void Initialize(ProblemDefinition problem, Randomization randomObj) { int j; if (problem.RealVariableCount != 0) { for (j = 0; j < problem.RealVariableCount; j++) { Xreal[j] = randomObj.RandomDouble(problem.MinRealvar[j], problem.MaxRealvar[j]); } } if (problem.BinaryVariableCount != 0) { for (j = 0; j < problem.BinaryVariableCount; j++) { for (int k = 0; k < problem.Nbits[j]; k++) { if (randomObj.RandomPercent() <= 0.5) { Gene[j][k] = 0; } else { Gene[j][k] = 1; } } } } }
/* 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); } }