// Find community information in each module public static void FindCommunity(double Alfa, List <List <int> > Modules, double[,] WeightMatrix, List <ComponentStruct> VerticeMatrix, int[,] RelativeMotionMatrix, out List <List <List <int> > > Communities, out List <double> Modularity, out List <double[, ]> SubGraphs, out List <List <ComponentStruct> > SubVerticeMs, out List <int[, ]> SubRelativeMs) { int NumOfModules = Modules.Count; Communities = new List <List <List <int> > >(); Modularity = new List <double>(); SubGraphs = new List <double[, ]>(); SubVerticeMs = new List <List <ComponentStruct> >();;; SubRelativeMs = new List <int[, ]>(); double[,] WMIntraModules; int NumOfIteration = 5; double CrossOverRatio = 0.4; double MutationRatio = 0.05; List <int> NumOfPopulation = new List <int>(); List <int> NumOfGeneration = new List <int>(); List <List <int> > SubModules; double[] T_BestFitness; List <int> sublist = new List <int>(); MPCCD.MPCCDSubGraph(Modules, WeightMatrix, VerticeMatrix, RelativeMotionMatrix, out WMIntraModules, out SubGraphs, out SubVerticeMs, out SubRelativeMs); int x = 0; for (int i = 0; i < NumOfModules; i++) { NumOfPopulation.Add((int)(Modules[x].Count / 2) + 1); NumOfGeneration.Add(5 * Modules[x].Count); x++; } // find the maximum modularity in each module for (int i = 0; i < NumOfModules; i++) { GAModuleDiv.FindBestSolution_Multiple(SubGraphs[i], NumOfPopulation[i], NumOfGeneration[i], CrossOverRatio, MutationRatio, out SubModules, out T_BestFitness); double XX = T_BestFitness.Max(); if (T_BestFitness.Max() > Alfa) { Communities.Add(SubModules.ToList()); Modularity.Add(T_BestFitness.Max()); } else { SubModules.Clear(); for (int j = 0; j < Modules[i].Count; j++) { sublist.Add(j + 1); } SubModules.Add(sublist.ToList()); Communities.Add(SubModules); Modularity.Add(T_BestFitness.Max()); sublist.Clear(); } } }
// Find the best module division result through multiple iterations public static void FindBestSolution_Multiple(double[,] SymmWeightMatrix, int NumOfPopulation, int NumOfGeneration, double CrossOverRatio, double MutationRatio, out List <List <int> > Modules, out double[] BestFitness) { int NumOfIteration = 5; BestFitness = new double[NumOfGeneration]; Modules = new List <List <int> >(); for (int i = 0; i < NumOfIteration; i++) { double[] Fitness = new double[NumOfGeneration]; List <List <int> > Temp_Modules = new List <List <int> >(); GAModuleDiv.FindModule(NumOfPopulation, NumOfGeneration, CrossOverRatio, MutationRatio, SymmWeightMatrix, out Temp_Modules, out Fitness); if (i > 0) { if (BestFitness.Max() < Fitness.Max()) { Modules = Temp_Modules.ToList(); Array.Copy(Fitness, BestFitness, Fitness.Length); } } else { Modules = Temp_Modules.ToList(); Array.Copy(Fitness, BestFitness, Fitness.Length); } /* foreach (List<int> x in Modules) * { * foreach (int xx in x) * { * Console.Write(" "); * Console.Write(string.Join(" ", xx.ToString())); * } * Console.WriteLine("\n"); * } * * Console.WriteLine(BestFitness.Max().ToString()); * Console.WriteLine("\n"); * */ } }
// find the optimal module division result public static void FindModule(int NumOfPopulation, int NumOfGeneration, double CrossOverRatio, double MutationRatio, double[,] WeightMatrix, out List <List <int> > Modules, out double[] BestFitness) { int NumOfNode = WeightMatrix.GetLength(0); Modules = new List <List <int> >(); BestFitness = new double[NumOfGeneration]; int[] BestGene = new int[NumOfNode]; // the best gene in one generation double MaxFitness = 0; int[] MaxGene = new int[NumOfNode]; // the max gene in one generation int[,] InitialPop; int[,] OldPop = new int[NumOfPopulation, NumOfNode]; int[,] NewPop = new int[NumOfPopulation, NumOfNode]; int[][] AdjacentNodes; List <List <int> > Community = new List <List <int> >(); double[] Fitness; double[] OldFitness = new double[NumOfPopulation]; double[] NewFitness = new double[NumOfPopulation]; double[] AveFitness = new double[NumOfGeneration]; double[] Temp_NormalizeFitness = new double[NumOfPopulation]; double[] Temp_Fitness = new double[NumOfPopulation]; int SelectionFather = 0, SelectionMother = 0, CrossOverPosition = 0, MutationPosition = 0; double Temp_sum; int NumMax = 0; List <int> RowOfMax = new List <int>(); // Initialize the population GAModuleDiv.InitializePopulation(NumOfNode, NumOfPopulation, WeightMatrix, out InitialPop, out AdjacentNodes); GAModuleDiv.FitnessCalAll(InitialPop, AdjacentNodes, WeightMatrix, out Fitness); Array.Copy(InitialPop, OldPop, NumOfPopulation * NumOfNode); Array.Copy(Fitness, OldFitness, Fitness.Length); Random rnd = new Random(); //find the best solution for (int i = 0; i < NumOfGeneration; i++) { Temp_sum = 0; MaxFitness = OldFitness.Max(); AveFitness[i] = OldFitness.Sum() / NumOfPopulation; RowOfMax.Clear(); // find the row of the max for (int j = 0; j < NumOfPopulation; j++) { if (MaxFitness == OldFitness[j]) { RowOfMax.Add(j); } } for (int k = 0; k < OldPop.GetLength(1); k++) { MaxGene[k] = OldPop[RowOfMax[0], k]; } // copy the best gene to the first few rows if (i > 0) { if (MaxFitness > BestFitness[i - 1]) { BestFitness[i] = MaxFitness; Array.Copy(MaxGene, BestGene, NumOfNode); // copy the best rows /* for (int k = 0; k < RowOfMax.Count; k++) * { * for (int x = 0; x < NumOfNode; x++) * { * NewPop[k, x] = OldPop[RowOfMax[k], x]; * } * } * NumMax = RowOfMax.Count; * */ for (int x = 0; x < NumOfNode; x++) { NewPop[0, x] = OldPop[RowOfMax[0], x]; } NumMax = 1; } else { BestFitness[i] = BestFitness[i - 1]; for (int x = 0; x < NumOfNode; x++) { NewPop[0, x] = OldPop[RowOfMax[0], x]; } NumMax = 1; } } else { BestFitness[i] = MaxFitness; Array.Copy(MaxGene, BestGene, NumOfNode); // copy the best rows /*for (int k = 0; k < RowOfMax.Count; k++) * { * for (int x = 0; x < NumOfNode; x++) * { * NewPop[k, x] = OldPop[RowOfMax[k], x]; * } * } * NumMax = RowOfMax.Count;*/ for (int x = 0; x < NumOfNode; x++) { NewPop[0, x] = OldPop[RowOfMax[0], x]; } NumMax = 1; } // selection, normalization double[] Temp_NormalizeFitness1 = new double[NumOfPopulation]; for (int k = 0; k < NumOfPopulation; k++) { Temp_NormalizeFitness1[k] = OldFitness[k] + Math.Abs(OldFitness.Min()) + 0.01; } for (int k = 0; k < NumOfPopulation; k++) { Temp_NormalizeFitness[k] = Temp_NormalizeFitness1[k] / Temp_NormalizeFitness1.Sum(); } for (int k = 0; k < NumOfPopulation; k++) { Temp_sum = Temp_sum + Temp_NormalizeFitness[k]; Temp_Fitness[k] = Temp_sum; } for (int j = NumMax; j < NumOfPopulation; j++) { double Delta = rnd.NextDouble(); for (int k = 0; k < NumOfPopulation; k++) { if (Delta < Temp_Fitness[k]) { for (int x = 0; x < NumOfNode; x++) { NewPop[j, x] = OldPop[k, x]; } SelectionFather = k; break; } } ////////////////////////check NewPop from above to find why it does not work//////////////// // crossover SelectionMother = rnd.Next(0, NumOfPopulation); CrossOverPosition = rnd.Next(0, NumOfNode); double Delta2 = rnd.NextDouble(); if (Delta2 <= CrossOverRatio) { for (int k = 0; k < CrossOverPosition; k++) { NewPop[j, k] = OldPop[SelectionFather, k]; } for (int k = CrossOverPosition; k < NumOfNode; k++) { NewPop[j, k] = OldPop[SelectionMother, k]; } } // mutation double Delta3 = rnd.NextDouble(); MutationPosition = rnd.Next(0, NumOfNode); if (Delta3 <= MutationRatio) { NewPop[j, MutationPosition] = AdjacentNodes[MutationPosition][rnd.Next(0, AdjacentNodes[MutationPosition].GetLength(0))]; } } GAModuleDiv.FitnessCalAll(NewPop, AdjacentNodes, WeightMatrix, out NewFitness); Array.Copy(NewFitness, OldFitness, NumOfPopulation); Array.Copy(NewPop, OldPop, NumOfPopulation * NumOfNode); Array.Clear(NewPop, 0, NumOfPopulation * NumOfNode); Array.Clear(NewFitness, 0, NumOfPopulation); } GAModuleDiv.TransToCommunity(NumOfNode, BestGene, out Modules); }