public double FindCurrentValue(double[,] weight_array) { clsSOMTSP cloned = this.Clone(); cloned.FineTune(); cloned.RemoveUnnecessary(); return(cloned.EXfindTourValue(weight_array)); }
internal double findTourLength() { clsSOMTSP cloned = this.Clone(); cloned.Cities = this.Cities; cloned.FineTune(); cloned.RemoveUnnecessary(); return(cloned.EXfindTourValue(cities_d)); }
public clsMemeticSOM(int NumNN, int pop, double[,] weights, PointF[] inpCities, float Width, float Height) { popSize = pop; Cities = inpCities; WeightArray = weights; individuals = new clsSOMTSP[popSize]; fitnesses = new double[popSize]; for (int i = 0; i < popSize; i++) { int randomcity = rnd.Next(Cities.Length - 1); individuals[i] = new clsSOMTSP(NumNN, Cities, Cities[randomcity].X, Cities[randomcity].Y, Width, Height, 1000 * rnd.NextDouble()); } BestResult = new clsSOMTSP(NumNN, Cities, 0, 0, Width, Height, 100); }
private void MoveClonies(clsSOMTSP Imperialist, clsSOMTSP Colony) { List <distPos> distancesfromrandomCity1 = new List <distPos>(Imperialist.Weights.Length); List <distPos> distancesfromrandomCity2 = new List <distPos>(Colony.Weights.Length); int randomCity = rnd.Next(CitiesPosition.Length); for (int i = 0; i < Imperialist.Weights.Length; i++) { distancesfromrandomCity1.Add(new distPos(i, distance(Imperialist.Weights[i], CitiesPosition[randomCity]))); } for (int i = 0; i < Colony.Weights.Length; i++) { distancesfromrandomCity2.Add(new distPos(i, distance(Colony.Weights[i], CitiesPosition[randomCity]))); } distPos[] NearCities1 = distancesfromrandomCity1.OrderBy(o => o.Distance).Take(1).ToArray(); distPos[] NearCities2 = distancesfromrandomCity2.OrderBy(o => o.Distance).Take(1).ToArray(); int startImpIndex = (NearCities1[0].Position - SwapParameter / 2 < 0 ? Colony.Weights.Length + (NearCities1[0].Position - SwapParameter / 2) : NearCities1[0].Position - SwapParameter / 2); int startColIndex = (NearCities2[0].Position - SwapParameter / 2 < 0 ? Imperialist.Weights.Length + (NearCities2[0].Position - SwapParameter / 2) : NearCities2[0].Position - SwapParameter / 2); for (int i = 0; i < SwapParameter; i++) { if ((startColIndex + i < Colony.Weights.Length) && (startImpIndex + i < Imperialist.Weights.Length)) { Colony.Weights[startColIndex + i] = Imperialist.Weights[startImpIndex + i]; Colony.Wins[startColIndex + i] = Imperialist.Wins[startImpIndex + i]; } else { if (startColIndex + i >= Colony.Weights.Length) { startColIndex = -i; } if (startImpIndex + i >= Imperialist.Weights.Length) { startImpIndex = -i; } Colony.Weights[startColIndex + i] = Imperialist.Weights[startImpIndex + i]; Colony.Wins[startColIndex + i] = Imperialist.Wins[startImpIndex + i]; } } }
public clsSOMTSP Clone() { clsSOMTSP tmp = new clsSOMTSP(Wins.Length, Cities, landa, false); tmp.Weights = (PointF[])this.Weights.Clone(); tmp.Wins = (int[])this.Wins.Clone(); //tmp.cities_d = (double[,])this.cities_d.Clone(); tmp.CurrentValue = this.CurrentValue; tmp.attachedEmpire = this.attachedEmpire; tmp.ColonyNumber = this.ColonyNumber; tmp.averageOfClonyfitness = this.averageOfClonyfitness; tmp._baseBeta = this._baseBeta; //tmp.d = (int[,])d.Clone(); tmp.firstX0 = this.firstX0; tmp.firstY0 = this.firstY0; tmp.firstWidth = this.firstWidth; tmp.firstHeight = this.firstHeight; tmp.landa = this.landa; return(tmp); }
public double[] RunEpoch(int MaxEpoch, int currentEpoch) { long st = Environment.TickCount; #region "Reveloution" for (int k = 0; k < ICA_Sols.Count; k++) { if (rnd.NextDouble() < PRev) { for (int i = 0; i < CitiesPosition.Length; i++) { ICA_Sols[k].Learn(MaxEpoch, MaxEpoch / 4); } //ICA_Sols[k].CurrentValue = ICA_Sols[k].FindCurrentValue(weight_array); } } #endregion long rev = Environment.TickCount; #region "Move Clonies" foreach (int k in Imperialists.Keys) { for (int i = 0; i < ICA_Sols.Count; i++) { if (ICA_Sols[i].attachedEmpire == Imperialists[k].attachedEmpire) { MoveClonies(Imperialists[k], ICA_Sols[i]); } } } #endregion long move = Environment.TickCount; #region "Upgrade each colony" foreach (var item in ICA_Sols) { item.Value.Learn(MaxEpoch, CitiesPosition.Length + currentEpoch); item.Value.CurrentValue = item.Value.FindCurrentValue(weight_array); } #endregion long upgrade = Environment.TickCount; #region "Swap Clony with Imperialists" for (int k = 0; k < NumberOfImpearialist; k++) { if (Imperialists.ContainsKey(k)) { for (int i = 0; i < ICA_Sols.Count; i++) { if (ICA_Sols[i].attachedEmpire == Imperialists[k].attachedEmpire) { if (ICA_Sols[i].CurrentValue < Imperialists[k].CurrentValue) { clsSOMTSP tmpSol = Imperialists[k].Clone(); Imperialists[k] = ICA_Sols[i].Clone(); ICA_Sols[i] = tmpSol; } } } } } #endregion long swap = Environment.TickCount; #region "Find nurtalized colony" for (int i = 0; i < ICA_Sols.Count; i++) { if (ICA_Sols[i].CurrentValue == Imperialists[ICA_Sols[i].attachedEmpire].CurrentValue) { int selaRandomImp = (int)rnd.Next(Imperialists.Keys.Min(), Imperialists.Keys.Max()); int NoiseRedius = (int)Math.Round(Math.Sqrt((ICA_Sols[i].firstHeight * ICA_Sols[i].firstHeight) + (ICA_Sols[i].firstWidth * ICA_Sols[i].firstWidth))) / 20; int start = rnd.Next(0, ICA_Sols[i].Weights.Length / 2); int end = rnd.Next(ICA_Sols[i].Weights.Length / 2 + 1, ICA_Sols[i].Weights.Length); if (Imperialists.ContainsKey(selaRandomImp)) { for (int j = start; j < end; j++) { ICA_Sols[i].Weights[j] = new PointF(Imperialists[selaRandomImp].Weights[j].X + rnd.Next(-NoiseRedius, NoiseRedius), Imperialists[selaRandomImp].Weights[j].Y + rnd.Next(-NoiseRedius, NoiseRedius)); ICA_Sols[i].Wins[j] = Imperialists[selaRandomImp].Wins[j]; } ICA_Sols[i].CurrentValue = ICA_Sols[i].FindCurrentValue(weight_array); } else { for (int j = start; j < end; j++) { ICA_Sols[i].Weights[j] = new PointF(ICA_Sols[i].Weights[j].X + rnd.Next(-NoiseRedius / 20, NoiseRedius / 20), ICA_Sols[i].Weights[j].Y + rnd.Next(-NoiseRedius / 20, NoiseRedius / 20)); } ICA_Sols[i].CurrentValue = ICA_Sols[i].FindCurrentValue(weight_array); } } } #endregion #region "Imperialist Challenges" double WorstVal = double.MinValue; int minIndex = -1; int weakestImperialist = -1; Dictionary <int, clsSOMTSP> .KeyCollection ImpKeys = Imperialists.Keys; double[] SumOfFitnesses = new double[NumberOfImpearialist]; for (int i = 0; i < ICA_Sols.Count; i++) { SumOfFitnesses[ICA_Sols[i].attachedEmpire] += ICA_Sols[i].CurrentValue; } foreach (int k in ImpKeys) { Imperialists[k].ColonyNumber = ICA_Sols.Count(p => p.Value.attachedEmpire == k); Imperialists[k].averageOfClonyfitness = SumOfFitnesses[k] / (Imperialists[k].ColonyNumber == 0 ? 1 : Imperialists[k].ColonyNumber); } if (Imperialists.Count > 1) { foreach (int i in ImpKeys) { if (Imperialists[i].CurrentValue > WorstVal) { WorstVal = Imperialists[i].CurrentValue; weakestImperialist = i; } } WorstVal = double.MinValue; for (int i = 0; i < ICA_Sols.Count; i++) { if (ICA_Sols[i].attachedEmpire == Imperialists[weakestImperialist].attachedEmpire) { if (ICA_Sols[i].CurrentValue > WorstVal) { WorstVal = ICA_Sols[i].CurrentValue; minIndex = i; } } } if (minIndex != -1) { double MaxTH = double.MinValue; double SumofNTH = 0; double[] TH = new double[NumberOfImpearialist]; double[] NTH = new double[NumberOfImpearialist]; double[] Z = new double[NumberOfImpearialist]; double maxZ = double.MinValue; int ZIndex = 0; foreach (int k in ImpKeys) { TH[k] = Imperialists[k].CurrentValue + 0.5 * Imperialists[k].averageOfClonyfitness; if (TH[k] > MaxTH) { MaxTH = TH[k]; } } foreach (int k in ImpKeys) { NTH[k] = MaxTH - TH[k]; SumofNTH += NTH[k]; } foreach (int k in ImpKeys) { Z[k] = Math.Abs(NTH[k] / SumofNTH) - rnd.NextDouble(); if (Z[k] > maxZ && k != ICA_Sols[minIndex].attachedEmpire) { maxZ = Z[k]; ZIndex = k; } } ICA_Sols[minIndex].attachedEmpire = Imperialists[ZIndex].attachedEmpire; } } #endregion long challenge = Environment.TickCount; #region "Imperialist elimination" if (Imperialists.Count > 1) { bool[] delete = new bool[NumberOfImpearialist]; foreach (int k in ImpKeys) { delete[k] = false; if (Imperialists[k].ColonyNumber == 0) { delete[k] = true; } } for (int k = delete.Length - 1; k >= 0; k--) { if (delete[k] == true) { Imperialists.Remove(k); } } } #endregion long elimination = Environment.TickCount; #region "Save Best Results" ////////////////////////////////////////////////////////////// double BestValue = double.MaxValue; double AverageValue = 0; foreach (int i in Imperialists.Keys) { if (Imperialists[i].CurrentValue < BestValue) { BestValue = Imperialists[i].CurrentValue; if (BestValue < BestGlobalValue) { BestGlobalValue = BestValue; BestSol = Imperialists[i].Clone(); } } } for (int i = 0; i < ICA_Sols.Count; i++) { AverageValue += ICA_Sols[i].CurrentValue; if (ICA_Sols[i].CurrentValue < BestValue) { BestValue = ICA_Sols[i].CurrentValue; if (BestValue < BestGlobalValue) { BestGlobalValue = BestValue; BestSol = ICA_Sols[i].Clone(); } } } AverageValue /= ICA_Sols.Count; #endregion long saveBest = Environment.TickCount; double perRev = (double)(rev - st) / (saveBest - st); double perMov = (double)(move - rev) / (saveBest - st); double perUpg = (double)(upgrade - move) / (saveBest - st); double perSwp = (double)(swap - upgrade) / (saveBest - st); double perCha = (double)(challenge - swap) / (saveBest - st); double perDel = (double)(elimination - challenge) / (saveBest - st); double perSav = (double)(saveBest - elimination) / (saveBest - st); return(new double[3] { BestValue, AverageValue, Imperialists.Count }); }
internal bool Merge(clsSOMTSP neighbour) { // finding nearest city between current TSP and neighbour PointF[] Copy_Of_Weights = new PointF[Weights.Length + neighbour.Weights.Length]; PointF[] Copy_Of_Cities = new PointF[Cities.Length + neighbour.Cities.Length - 1]; int[] Copy_Of_Wins = new int[Weights.Length + neighbour.Weights.Length]; int merger_counter = 0; double min_dist = double.MaxValue; int min_index_src = -1, min_index_dst = -1, min_index_dst_1 = 0, min_index_src_1 = 0; PointF A, B, C, D; //double toleration = 1; for (int ii = 0; ii < Weights.Length; ii++) { for (int jj = 0; jj < neighbour.Weights.Length; jj++) { double dist = distance(Weights[ii], neighbour.Weights[jj]); if (dist < min_dist /** toleration*/) { //toleration = 1 + rnd.NextDouble() * 0.01; min_dist = dist; min_index_src = ii; min_index_dst = jj; } } } PointF[] Candidate_C = new PointF[2]; int[] Candidate_C_Index = new int[2]; PointF[] Candidate_D = new PointF[2]; int[] Candidate_D_Index = new int[2]; bool[] Directions = new bool[2]; A = D = Weights[min_index_src]; B = C = neighbour.Weights[min_index_dst]; bool NotAssigned = true; for (int ii = min_index_dst; ii >= 0; ii--) { if (neighbour.FindRealIndex(neighbour.Weights[ii]) != neighbour.FindRealIndex(B)) { Candidate_C[0] = neighbour.Weights[ii]; Candidate_C_Index[0] = ii; NotAssigned = false; break; } } if (NotAssigned == true) { for (int ii = neighbour.Weights.Length - 1; ii > min_index_dst; ii--) { if (neighbour.FindRealIndex(neighbour.Weights[ii]) != neighbour.FindRealIndex(B)) { Candidate_C[0] = neighbour.Weights[ii]; Candidate_C_Index[0] = ii; break; } } } NotAssigned = true; for (int ii = min_index_dst; ii < neighbour.Weights.Length; ii++) { if (neighbour.FindRealIndex(neighbour.Weights[ii]) != neighbour.FindRealIndex(B)) { Candidate_C[1] = neighbour.Weights[ii]; Candidate_C_Index[1] = ii; NotAssigned = false; break; } } if (NotAssigned == true) { for (int ii = 0; ii < min_index_dst; ii++) { if (neighbour.FindRealIndex(neighbour.Weights[ii]) != neighbour.FindRealIndex(B)) { Candidate_C[1] = neighbour.Weights[ii]; Candidate_C_Index[1] = ii; break; } } } NotAssigned = true; for (int ii = min_index_src; ii < Weights.Length; ii++) { if (FindRealIndex(Weights[ii]) != FindRealIndex(A)) { Candidate_D[0] = Weights[ii]; Candidate_D_Index[0] = ii; NotAssigned = false; break; } } if (NotAssigned == true) { for (int ii = 0; ii < min_index_src; ii++) { if (FindRealIndex(Weights[ii]) != FindRealIndex(A)) { Candidate_D[0] = Weights[ii]; Candidate_D_Index[0] = ii; break; } } } NotAssigned = true; for (int ii = min_index_src; ii >= 0; ii--) { if (FindRealIndex(Weights[ii]) != FindRealIndex(A)) { Candidate_D[1] = Weights[ii]; Candidate_D_Index[1] = ii; NotAssigned = false; break; } } if (NotAssigned == true) { for (int ii = Weights.Length - 1; ii > min_index_src; ii--) { if (FindRealIndex(Weights[ii]) != FindRealIndex(A)) { Candidate_D[1] = Weights[ii]; Candidate_D_Index[1] = ii; break; } } } double min_dist_vec = double.MaxValue; for (int numC = 0; numC < 2; numC++) { for (int numD = 0; numD < 2; numD++) { if (distance(Candidate_C[numC], Candidate_D[numD]) < min_dist_vec) { min_dist_vec = distance(Candidate_C[numC], Candidate_D[numD]); C = Candidate_C[numC]; D = Candidate_D[numD]; min_index_dst_1 = Candidate_C_Index[numC]; min_index_src_1 = Candidate_D_Index[numD]; if (numC == 0) { Directions[0] = false; // Decrease } else { Directions[0] = true; // Increase } if (numD == 0) { Directions[1] = true; // Increase } else { Directions[1] = false; // Decrease } } } } Copy_Of_Weights[merger_counter] = Weights[min_index_src]; //A Copy_Of_Wins[merger_counter] = Wins[min_index_src]; merger_counter++; if (Directions[0] == false) { int k = min_index_dst; while (true) { if (k == min_index_dst_1) // we reached to C from B { break; } Copy_Of_Weights[merger_counter] = neighbour.Weights[k]; Copy_Of_Wins[merger_counter] = neighbour.Wins[k]; merger_counter++; if (k == neighbour.Weights.Length - 1) { k = 0; } else { k++; } } } else { int k = min_index_dst; while (true) { if (k == min_index_dst_1) // we reached to C from B { break; } Copy_Of_Weights[merger_counter] = neighbour.Weights[k]; Copy_Of_Wins[merger_counter] = neighbour.Wins[k]; merger_counter++; if (k == 0) { k = neighbour.Weights.Length - 1; } else { k--; } } } Copy_Of_Weights[merger_counter] = neighbour.Weights[min_index_dst_1]; //C Copy_Of_Wins[merger_counter] = neighbour.Wins[min_index_dst_1]; merger_counter++; if (Directions[1] == true) { int k = min_index_src_1; while (true) { if (k == min_index_src) // we reached to D from A { break; } Copy_Of_Weights[merger_counter] = Weights[k]; Copy_Of_Wins[merger_counter] = Wins[k]; merger_counter++; if (k == Weights.Length - 1) { k = 0; } else { k++; } } } else { int k = min_index_src_1; while (true) { if (k == min_index_src) // we reached to D from A { break; } Copy_Of_Weights[merger_counter] = Weights[k]; Copy_Of_Wins[merger_counter] = Wins[k]; merger_counter++; if (k == 0) { k = Weights.Length - 1; } else { k--; } } } Array.Resize(ref Copy_Of_Weights, merger_counter); Array.Resize(ref Copy_Of_Wins, merger_counter); for (int i = 0; i < Cities.Length; i++) { Copy_Of_Cities[i] = Cities[i]; } for (int i = 1; i < neighbour.Cities.Length; i++) { Copy_Of_Cities[Cities.Length + i - 1] = neighbour.Cities[i]; } Cities = Copy_Of_Cities; Weights = Copy_Of_Weights; Wins = Copy_Of_Wins; BreakTie(); FindAllWeights_Array(); //FindAllD(); return(true); }