protected override int ChooseNext(Route route) { if (route.Count == 0) { return(0); } if (_testRoute == null || _testRoute.Graph != route.Graph) { _testRoute = new Route(route.Graph); } int best = -1; int bestVal = -1; int score = Int32.MaxValue; for (int i = route.Count; i < route.Graph.Count; ++i) { int val = route.GetFromSelectionBuffer(i); _testRoute.Clear(); _testRoute.Copy(route); _testRoute.AddEnd(i); Improver.Improve(_testRoute, false); int dist = _testRoute.Length; if (dist < score || (dist == score && val < bestVal)) { best = i; bestVal = val; score = dist; } } return(best); }
public Route Search(Graph graph, bool printProgress = false) { if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Starting a new {0} search with {1} thread{2}", GetType().Name, Threads, Threads != 1 ? "s" : ""); Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine("Search will use {0} for each iteration", Searcher.GetType().Name); Console.ForegroundColor = ConsoleColor.Green; Console.Write("Progress: 0/{0} - 0", Attempts); Console.ForegroundColor = ConsoleColor.White; } Route best = null; int attempt = 0; int exited = 0; Func<bool> next = () => { lock (this) { if (attempt < Attempts) { ++attempt; return true; } return false; } }; Func<bool> hasNext = () => { lock (this) return attempt < Attempts; }; Func<bool> ended = () => { lock (this) return exited == Threads; }; Action exit = () => { lock (this) ++exited; }; Action rejoin = () => { lock (this) --exited; }; Func<bool> waitForEnd = () => { exit(); while (!hasNext() && !ended()) Thread.Yield(); if (!ended()) { rejoin(); return false; } else return true; }; Action<Route> compare = (route) => { lock (this) { if (best == null || route.Length < best.Length) { best = new Route(route); attempt = 0; if (BetterRouteFound != null) BetterRouteFound(this, new BetterRouteFoundEventArgs(route)); } else if (attempt % (Attempts >> 4) == 0) _rand = new Random(); if (printProgress) { Console.CursorLeft = 10; Console.Write("{0}/{1} - {2} ", attempt, Attempts, best.Length); } } }; ThreadStart loop = () => { Route route = new Route(graph); for (; ; ) { while (next()) { route.Clear(); for (int i = 0; i < graph.Count; ++i) { lock (_rand) route.AddEnd(_rand.Next(i, graph.Count)); Searcher.Improve(route); } compare(route); } if (waitForEnd()) break; } }; Thread[] workers = new Thread[Threads - 1]; for (int i = 0; i < workers.Length; ++i) { workers[i] = new Thread(loop); workers[i].Start(); } loop(); if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("\n{0} search complete", GetType().Name); Console.ForegroundColor = ConsoleColor.White; } return best; }
public override void Improve(Route route, bool printProgress = false) { _genePool = new GeneticRoute[GenePoolCount]; _selected = new GeneticRoute[SelectionCount]; if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Starting a new {0} search", GetType().Name); Console.WriteLine("Creating initial population..."); Console.Write("Progress: 0/{0}", GenePoolCount); Console.ForegroundColor = ConsoleColor.White; } ReversingSearcher improver = new ReversingSearcher(); _genePool[0] = new GeneticRoute(route); _genePool[0].Fitness = route.Length; for (int i = 1; i < GenePoolCount; ++i) { _genePool[i] = new GeneticRoute(route.Graph, _rand); _genePool[i].Fitness = _genePool[i].Length; //Route clone = new Route(_genePool[i]); //improver.Improve(clone, false); //_genePool[i].Fitness = clone.Length; if (printProgress) { Console.CursorLeft = 10; Console.Write("{0}/{1}", i + 1, GenePoolCount); } } if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Console.WriteLine("Initial population created"); Console.WriteLine("Running generations..."); Console.Write("Progress: 0/{0} - 0", GenerationLimit); Console.ForegroundColor = ConsoleColor.White; } for (int g = 0; g < GenerationLimit; ++g) { if (printProgress) { Console.CursorLeft = 10; Console.Write("{0}/{1} - {2} ", g + 1, GenerationLimit, _genePool[0].Fitness); } for (int i = 0; i < SelectionCount; ++i) { int j = 0; while (IsSelected(i, j) || _rand.NextDouble() >= SelectionQuality) { j = (j + 1) % GenePoolCount; } _selected[i] = _genePool[j]; } for (int i = 0; i < OffspringCount; ++i) { GeneticRoute parentA = _selected[0]; // TODO: fix for different GeneticRoute parentB = _selected[1]; // selection counts ushort[] genes = new ushort[route.Count]; Crossover(genes, parentA.Genes, parentB.Genes); Mutate(genes); GeneticRoute child = new GeneticRoute(route.Graph, genes); //Route clone = new Route(child); //improver.Improve(clone, false); //child.Fitness = clone.Length; child.Fitness = child.Length; int l = -1; for (int j = GenePoolCount - 1; j >= 0; --j) { GeneticRoute other = _genePool[j]; if (other.Fitness > child.Fitness) { _genePool[j] = child; if (l > -1) _genePool[l] = other; if (j == 0) { BetterRouteFound(this, new BetterRouteFoundEventArgs(child)); g = 0; } l = j; } else break; } } } if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("\nGenetic search complete"); Console.ForegroundColor = ConsoleColor.White; } Route best = new Route(_genePool[0]); improver.Improve(best); route.Clear(); for (int i = 0; i < best.Count; ++i) route.Insert(route.VIndexOf(best[i]), i); }
public Route Search(Graph graph, bool printProgress = false) { if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Starting a new {0} search with {1} thread{2}", GetType().Name, Threads, Threads != 1 ? "s" : ""); Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine("Search will use {0} for each iteration", Searcher.GetType().Name); Console.ForegroundColor = ConsoleColor.Green; Console.Write("Progress: 0/{0} - 0", Attempts); Console.ForegroundColor = ConsoleColor.White; } Route best = null; int attempt = 0; int exited = 0; Func <bool> next = () => { lock (this) { if (attempt < Attempts) { ++attempt; return(true); } return(false); } }; Func <bool> hasNext = () => { lock (this) return(attempt < Attempts); }; Func <bool> ended = () => { lock (this) return(exited == Threads); }; Action exit = () => { lock (this) ++exited; }; Action rejoin = () => { lock (this) --exited; }; Func <bool> waitForEnd = () => { exit(); while (!hasNext() && !ended()) { Thread.Yield(); } if (!ended()) { rejoin(); return(false); } else { return(true); } }; Action <Route> compare = (route) => { lock (this) { if (best == null || route.Length < best.Length) { best = new Route(route); attempt = 0; if (BetterRouteFound != null) { BetterRouteFound(this, new BetterRouteFoundEventArgs(route)); } } else if (attempt % (Attempts >> 4) == 0) { _rand = new Random(); } if (printProgress) { Console.CursorLeft = 10; Console.Write("{0}/{1} - {2} ", attempt, Attempts, best.Length); } } }; ThreadStart loop = () => { Route route = new Route(graph); for (; ;) { while (next()) { route.Clear(); for (int i = 0; i < graph.Count; ++i) { lock (_rand) route.AddEnd(_rand.Next(i, graph.Count)); Searcher.Improve(route); } compare(route); } if (waitForEnd()) { break; } } }; Thread[] workers = new Thread[Threads - 1]; for (int i = 0; i < workers.Length; ++i) { workers[i] = new Thread(loop); workers[i].Start(); } loop(); if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("\n{0} search complete", GetType().Name); Console.ForegroundColor = ConsoleColor.White; } return(best); }
public override void Improve(Route route, bool printProgress = false) { _genePool = new GeneticRoute[GenePoolCount]; _selected = new GeneticRoute[SelectionCount]; if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Starting a new {0} search", GetType().Name); Console.WriteLine("Creating initial population..."); Console.Write("Progress: 0/{0}", GenePoolCount); Console.ForegroundColor = ConsoleColor.White; } ReversingSearcher improver = new ReversingSearcher(); _genePool[0] = new GeneticRoute(route); _genePool[0].Fitness = route.Length; for (int i = 1; i < GenePoolCount; ++i) { _genePool[i] = new GeneticRoute(route.Graph, _rand); _genePool[i].Fitness = _genePool[i].Length; //Route clone = new Route(_genePool[i]); //improver.Improve(clone, false); //_genePool[i].Fitness = clone.Length; if (printProgress) { Console.CursorLeft = 10; Console.Write("{0}/{1}", i + 1, GenePoolCount); } } if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(); Console.WriteLine("Initial population created"); Console.WriteLine("Running generations..."); Console.Write("Progress: 0/{0} - 0", GenerationLimit); Console.ForegroundColor = ConsoleColor.White; } for (int g = 0; g < GenerationLimit; ++g) { if (printProgress) { Console.CursorLeft = 10; Console.Write("{0}/{1} - {2} ", g + 1, GenerationLimit, _genePool[0].Fitness); } for (int i = 0; i < SelectionCount; ++i) { int j = 0; while (IsSelected(i, j) || _rand.NextDouble() >= SelectionQuality) { j = (j + 1) % GenePoolCount; } _selected[i] = _genePool[j]; } for (int i = 0; i < OffspringCount; ++i) { GeneticRoute parentA = _selected[0]; // TODO: fix for different GeneticRoute parentB = _selected[1]; // selection counts ushort[] genes = new ushort[route.Count]; Crossover(genes, parentA.Genes, parentB.Genes); Mutate(genes); GeneticRoute child = new GeneticRoute(route.Graph, genes); //Route clone = new Route(child); //improver.Improve(clone, false); //child.Fitness = clone.Length; child.Fitness = child.Length; int l = -1; for (int j = GenePoolCount - 1; j >= 0; --j) { GeneticRoute other = _genePool[j]; if (other.Fitness > child.Fitness) { _genePool[j] = child; if (l > -1) { _genePool[l] = other; } if (j == 0) { BetterRouteFound(this, new BetterRouteFoundEventArgs(child)); g = 0; } l = j; } else { break; } } } } if (printProgress) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("\nGenetic search complete"); Console.ForegroundColor = ConsoleColor.White; } Route best = new Route(_genePool[0]); improver.Improve(best); route.Clear(); for (int i = 0; i < best.Count; ++i) { route.Insert(route.VIndexOf(best[i]), i); } }