/// <summary> /// "Mutates" a given individual by executing a local search 3-Opt operation. /// </summary> /// <param name="solver"></param> /// <param name="mutating"></param> /// <returns></returns> public Individual <MaxTimeSolution, MaxTimeProblem, Fitness> Mutate( Solver <MaxTimeSolution, MaxTimeProblem, Fitness> solver, Individual <MaxTimeSolution, MaxTimeProblem, Fitness> mutating) { // select a random route. MaxTimeSolution mutated = (mutating.Genomes.Clone() as MaxTimeSolution); IRoute route = mutated.Route( OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(mutated.Count)); // apply the improvement operator. double difference; OsmSharp.Math.TSP.LocalSearch.HillClimbing3Opt.HillClimbing3OptSolver hillclimbing_3opt = new OsmSharp.Math.TSP.LocalSearch.HillClimbing3Opt.HillClimbing3OptSolver(true, true); hillclimbing_3opt.Improve(solver.Problem, route, out difference); return(new Individual <MaxTimeSolution, MaxTimeProblem, Fitness>( mutated)); }
/// <summary> /// Does the mutation. /// </summary> /// <param name="solver"></param> /// <param name="mutating"></param> /// <returns></returns> public Individual <MaxTimeSolution, MaxTimeProblem, Fitness> Mutate( Solver <MaxTimeSolution, MaxTimeProblem, Fitness> solver, Individual <MaxTimeSolution, MaxTimeProblem, Fitness> mutating) { MaxTimeSolution solution = (mutating.Genomes.Clone() as MaxTimeSolution); //MaxTimeSolution copy = (mutating.Genomes.Clone() as MaxTimeSolution); if (solution.Count > 1) { // calculate average. int avg = solution.Size / solution.Count; // int source_route_idx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(solution.Count); // get the source count and descide what to do. List <int> sizes = new List <int>(solution.Sizes); int source_size = solution.Sizes[source_route_idx]; if (source_size > avg) { int size = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(source_size / 2); //int size = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(source_size); //int size = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(source_size / 3); if (size > 0) { sizes[source_route_idx] = sizes[source_route_idx] - size; } sizes.Insert(source_route_idx, size); } else { // route is small; add it to a neighbour route. int target_route_idx = -1; do { target_route_idx = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(solution.Sizes.Count); } while (source_route_idx == target_route_idx); if (target_route_idx >= 0 && target_route_idx < sizes.Count) { // merge the two into the target; int size = sizes[source_route_idx]; sizes[target_route_idx] = sizes[target_route_idx] + size; sizes.RemoveAt(source_route_idx); } } // remove all zero's. while (sizes.Remove(0)) { } solution = this.ChangeSizes(solver.Problem, solution, sizes); // apply 3Opt to all routes. for (int route_idx = 0; route_idx < solution.Count; route_idx++) { double difference; OsmSharp.Math.TSP.LocalSearch.HillClimbing3Opt.HillClimbing3OptSolver hillclimbing_3opt = new OsmSharp.Math.TSP.LocalSearch.HillClimbing3Opt.HillClimbing3OptSolver(true, true); hillclimbing_3opt.Improve(solver.Problem, solution.Route(route_idx), out difference); } if (!solution.IsValid()) { throw new Exception(); } } return(new Individual <MaxTimeSolution, MaxTimeProblem, Fitness>(solution)); }