private Offspring Crossover(SetCoveringProblemData data, int [] chromosome, int [] chromosome2, int n) { var offspring1 = new int[n]; var offspring2 = new int[n]; int k = Utility.Random.Next(n); for (int i = 0; i < k; ++i) { offspring1[i] = chromosome[i]; offspring2[i] = chromosome2[i]; } for (int i = k; i < n; ++i) { offspring1[i] = chromosome2[i]; offspring2[i] = chromosome[i]; } // for (int i = 0; i < 3; ++i) MutateChromosome(data, offspring1, n); //Uti(data, offspring1, n); // for (int i = 0; i < 3; ++i) MutateChromosome(data, offspring2, n); //AddMissingGenees(data, offspring2, n); return(FixOffSpringChromosomes(data, offspring1, offspring2, n)); }
private void Initialize(SetCoveringProblemData data) { _l = new int[PopulationSize, data.N]; _r = new int[data.M]; int t = 0; var res = new GreedyEngine.Engine().Solve(data); for (int i = 0; i < data.N; ++i) { _l[t, i] = res.Solution[i]; } //FindNextCovering(data, t, (d, r) => d.Subsets[r].First()); while (t < PopulationSize - 1) { t++; for (int j = 0; j < data.M; ++j) { _r[j] = 0; } FindNextCovering(data, t, (d, r) => d.Subsets[r][Utility.Random.Next(data.Subsets[r].Count)]); } DeleteExcessiveColumns(data); }
static SetCoveringProblemData ReadData(string file) { var result = new SetCoveringProblemData(); string content = File.ReadAllText(file); List <int> nums = content .Split(new[] { " ", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) .Select(x => int.Parse(x)) .ToList(); int counter = 2; int m = nums[0]; // number of rows int n = nums[1]; // number of columns counter += n; result.Subsets = new List <List <int> >(m); for (int j = 0; j < m; ++j) { int capacity = nums[counter++]; var subset = new List <int>(capacity); for (int k = 0; k < capacity; ++k) { subset.Add(nums[counter++] - 1); } result.Subsets.Add(subset); } result.N = n; result.M = m; return(result); }
private Offspring FixOffSpringChromosomes(SetCoveringProblemData data, int [] chromosome, int [] chromosome2, int n) { Utility.AddMissingSetToCover(data, chromosome, n); Utility.DeleteExcessiveSetsFromCover(data, chromosome); Utility.AddMissingSetToCover(data, chromosome2, n); Utility.DeleteExcessiveSetsFromCover(data, chromosome2); return(new Offspring() { Chromosome1 = chromosome, Chromsome2 = chromosome2 }); }
public SetCoveringProblemResult Solve(SetCoveringProblemData data) { var universal = new List <int>(); for (int i = 1; i <= data.M; ++i) { universal.Add(i); } int iterations = 0; int[] solution = new int[data.N]; int solutionFitness = 0; while (universal.Any()) { iterations++; int maxIndex = 0; int max = 0; for (int j = 0; j < data.N; ++j) { if (solution[j] != 1) { var intersecting = universal.Intersect(data.SubsetsWithBelongingElements[j]).Count(); if (intersecting > max) { max = intersecting; maxIndex = j; } } } universal = universal.Except(data.SubsetsWithBelongingElements[maxIndex]).ToList(); solution[maxIndex] = 1; solutionFitness++; } return(new SetCoveringProblemResult() { Iterations = iterations, Solution = solution, SolutionFitness = solutionFitness }); }
private void FindNextCovering(SetCoveringProblemData data, int t, Func <SetCoveringProblemData, int, int> nextCoveringFunction) { int r = 0; while (r != -1) { int j1 = nextCoveringFunction(data, r); _l[t, j1] = 1; for (int l = 0; l < data.M; ++l) { _r[l] = _r[l] + data.A[l, j1]; } r = Array.IndexOf(_r, 0); } }
private void DeleteExcessiveColumns(SetCoveringProblemData data) { for (int k = 0; k < PopulationSize; ++k) { var chromosome = new int[data.N]; for (int i = 0; i < data.N; ++i) { chromosome[i] = _l[k, i]; } Utility.DeleteExcessiveSetsFromCover(data, chromosome); for (int i = 0; i < data.N; ++i) { _l[k, i] = chromosome[i]; } } }
private void MutateChromosome(SetCoveringProblemData data, int [] chromosome, int n) { int k = Utility.Random.Next(n); var probabilityOfMutation = 1.0 / E(data, k); double probabilityDivistionFactor = 0; for (int i = 0; i < n; ++i) { probabilityDivistionFactor += 1.0 / E(data, i); } probabilityOfMutation /= probabilityDivistionFactor; if (probabilityOfMutation > 1.0 / n && data.ColumnCount(0, k) > data.ColumnCount(1, k)) { chromosome[k] = (chromosome[k] + 1) % 2; } }
private int [] Initialize(SetCoveringProblemData data) { int [] solution = new int[data.N]; int[] rArray = new int[data.M]; int r = 0; while (r != -1) { int j1 = data.Subsets[r].First(); solution[j1] = 1; for (int l = 0; l < data.M; ++l) { rArray[l] = rArray[l] + data.A[l, j1]; } r = Array.IndexOf(rArray, 0); } return(solution); }
public SetCoveringProblemResult Solve(SetCoveringProblemData data) { double t = 1000000; double tStop = 0.02; double alfa = 0.98; int iterations = 0; //var res = new GreedyEngine.Engine().Solve(data); var configuration = Initialize(data); while (t > tStop) { iterations++; int [] oldConfiguration = new int[data.N]; Array.Copy(configuration, oldConfiguration, data.N); int oldFitness = Utility.CalculateConfigurationFitness(data, configuration, data.N); if (Utility.Random.NextDouble() >= 0.5) { int k1 = Utility.Random.Next(data.N); int k2 = Utility.Random.Next(data.N); int temp = configuration[k1]; configuration[k1] = configuration[k2]; configuration[k2] = temp; } else { int k1 = Utility.Random.Next(data.N); configuration[k1] = (configuration[k1] + 1) % 2; } Utility.AddMissingSetToCover(data, configuration, data.N); Utility.DeleteExcessiveSetsFromCover(data, configuration); int newFitness = Utility.CalculateConfigurationFitness(data, configuration, data.N); //Console.WriteLine("iteration: " + iterations); //Console.WriteLine("fitness: " + newFitness); if (newFitness > oldFitness) { double acceptProbability = 1.0 / Math.Exp((newFitness - oldFitness) / t); if (Utility.Random.NextDouble() > acceptProbability) { Array.Copy(oldConfiguration, configuration, data.N); } } t *= alfa; } int finalFitness = Utility.CalculateConfigurationFitness(data, configuration, data.N); return(new SetCoveringProblemResult() { Iterations = iterations, Solution = configuration, SolutionFitness = finalFitness }); }
private double E(SetCoveringProblemData data, int j) { return(-data.ColumnCount(0, j) * Math.Log(data.ColumnCount(0, j)) - data.ColumnCount(1, j) * Math.Log(data.ColumnCount(1, j))); }
public SetCoveringProblemResult Solve(SetCoveringProblemData data) { Initialize(data); int iterations = 0; List <int> fitnessesHistory = new List <int>(); int solution = 1000000000; int solutionIndex = 0; while (iterations < 3000) { //Console.WriteLine("Iteration: " + iterations); var fitnesses = new List <PopulationEntry>(); for (int i = 0; i < PopulationSize; ++i) { var fitness = Utility.CalculateConfigurationFitness(data, GetChromosomeFromPopulation(i, data.N), data.N); fitnesses.Add(new PopulationEntry { EntryFitness = fitness, EntryIndex = i }); } fitnesses = fitnesses.OrderBy(x => x.EntryFitness).ToList(); var offSpring = new Offspring(); if (iterations % 2 == 0) { offSpring = Crossover(data, GetChromosomeFromPopulation(fitnesses[0].EntryIndex, data.N), GetChromosomeFromPopulation(fitnesses[PopulationSize - 1].EntryIndex, data.N), data.N); } else { offSpring = Crossover(data, GetChromosomeFromPopulation(fitnesses[0].EntryIndex, data.N), GetChromosomeFromPopulation(fitnesses[1].EntryIndex, data.N), data.N); } var fitness1 = Utility.CalculateConfigurationFitness(data, offSpring.Chromosome1, data.N); var fitness2 = Utility.CalculateConfigurationFitness(data, offSpring.Chromsome2, data.N); if (fitness1 > fitness2) { for (int i = 0; i < data.N; ++i) { _l[fitnesses.Last().EntryIndex, i] = offSpring.Chromsome2[i]; } } else { for (int i = 0; i < data.N; ++i) { _l[fitnesses.Last().EntryIndex, i] = offSpring.Chromosome1[i]; } } var totalFitness = 0; for (int i = 0; i < PopulationSize; ++i) { var fitness = Utility.CalculateConfigurationFitness(data, GetChromosomeFromPopulation(i, data.N), data.N); totalFitness += fitness; } fitnessesHistory.Add(totalFitness); //Console.WriteLine("Population fitness: " + totalFitness); iterations++; solution = fitnesses[0].EntryFitness; solutionIndex = fitnesses[0].EntryIndex; if (iterations > 50 && fitnessesHistory[iterations - 50] == fitnessesHistory[iterations - 1]) { break; } } //Console.WriteLine("solution: " + solution); return(new SetCoveringProblemResult() { Iterations = iterations, Solution = GetChromosomeFromPopulation(solutionIndex, data.N), SolutionFitness = solution }); }
static void RunHeuristic(string name, Func <SetCoveringProblemData, SetCoveringProblemResult> logic, SetCoveringProblemData data) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var result = logic(data); stopwatch.Stop(); Console.WriteLine(name); Console.WriteLine("Iterations: " + result.Iterations); Console.WriteLine("Solution: " + result.SolutionFitness); Console.WriteLine("Time (s): " + stopwatch.ElapsedMilliseconds / 1000.0); Console.WriteLine(); }
public SetCoveringProblemResult Solve(SetCoveringProblemData data) { var res = new GreedyEngine.Engine().Solve(data); var configuration = res.Solution; //int upperBound = 10000000; double tsFactor = 0.2; int tabuLength = (int)Math.Ceiling(tsFactor * Utility.NumberOfSubsetsIncover(res.Solution, data.N)) + 1; int[] solution = new int[data.N]; Array.Copy(res.Solution, solution, data.N); int solutionFitness = res.SolutionFitness; int iterations = 0; List <int> fitnessesHistory = new List <int>(); while (iterations < 2000) { iterations++; List <int[]> neighborhood = new List <int[]>(); List <ConfigurationEntry> sortedNeighborhood = new List <ConfigurationEntry>(); for (int i = 0; i < data.N; ++i) { int[] neighbor = new int[data.N]; Array.Copy(configuration, neighbor, data.N); neighbor[i] = (neighbor[i] + 1) % 2; neighborhood.Add(neighbor); sortedNeighborhood.Add(new ConfigurationEntry { Index = i, Fitness = Utility.CalculateConfigurationFitness(data, neighbor, data.N) }); } var configurations = sortedNeighborhood.OrderBy(x => x.Fitness).ToList(); var acceptable = configurations.First(x => !BelongsToTabu(neighborhood[x.Index], data.N) || x.Fitness < solutionFitness); Array.Copy(neighborhood[acceptable.Index], configuration, data.N); if (acceptable.Fitness < solutionFitness && Utility.IsLegalSolution(data, neighborhood[acceptable.Index])) { solution = neighborhood[acceptable.Index]; solutionFitness = acceptable.Fitness; } if (_tabuList.Count == tabuLength + 2) { var first = _tabuList.First(); _tabuList.Remove(first); } _tabuList.Add(neighborhood[acceptable.Index]); fitnessesHistory.Add(solutionFitness); if (iterations > 100 && fitnessesHistory[iterations - 100] == fitnessesHistory[iterations - 1]) { break; } //Console.WriteLine("iterations: " + iterations); //Console.WriteLine("fitness: " + solutionFitness); } return(new SetCoveringProblemResult() { Iterations = iterations, Solution = solution, SolutionFitness = solutionFitness }); }