protected override int ChooseNext( Route route ) { if ( route.Count == 0 ) return 0; // New method which happens to be worse for the biggest graph: // best = route.SelectNextBest(); int last = route[route.Count - 1]; 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 ); int dist = route.Graph[last, val]; if ( dist < score || ( dist == score && val < bestVal ) ) { best = i; bestVal = val; score = dist; } } return best; }
protected override int ChooseNext( Route route ) { if ( route.Count == 0 ) return 0; return route.SelectNextBest( route.Graph.Count - route.Count - 1 ); }
public GeneticRoute(Route route) : base(route) { Genes = new ushort[Graph.Count]; UpdateGenesFromIndices(); }
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 virtual void Improve( Route route, bool printProgress = false ) { if ( printProgress ) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine( "# Starting a new {0} with route of length {1}", GetType().Name, route.Length ); Console.Write( "Current best: {0}", route.Length ); } if ( route.Count > 3 ) { while ( Iterate( route ) ) { if ( printProgress ) { Console.CursorLeft = 14; Console.Write( "{0} ", route.Length ); } } } if ( printProgress ) { Console.WriteLine( "\nPeak reached" ); Console.ForegroundColor = ConsoleColor.White; } }
public override bool Iterate(Route route) { int bestI = 0; int bestJ = 0; int bestScore = 0; for (int i = 0; i < route.Count; ++i) { int i0 = route[i - 1]; int i1 = route[i]; int i2 = route[i + 1]; int iS = route.Graph[i0, i1] + route.Graph[i1, i2]; for (int j = i + 1; j < route.Count; ++j) { int j0 = route[j - 1]; int j1 = route[j]; int j2 = route[j + 1]; int jS = route.Graph[j0, j1] + route.Graph[j1, j2]; int orig = iS + jS; if (j0 == i1) { j0 = j1; i2 = i1; } else if (i0 == j1) { i0 = i1; j2 = j1; } else { i0 = route[i - 1]; i2 = route[i + 1]; } int next = route.Graph[i0, j1] + route.Graph[j1, i2] + route.Graph[j0, i1] + route.Graph[i1, j2]; int score = orig - next; if (score > bestScore) { bestI = i; bestJ = j; bestScore = score; } } } if (bestScore > 0) { route.Swap(bestI, bestJ); return true; } return false; }
public Route Search( Graph graph, bool printProgress = false ) { Route route = new Route( graph ); if ( printProgress ) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine( "Starting a new {0} search", GetType().Name ); if ( Improver != null ) { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine( "Search will use {0} to " + "improve each iteration", Improver.GetType().Name ); } Console.ForegroundColor = ConsoleColor.Green; Console.Write( "Progress: 0/{0} - 0", graph.Count ); Console.ForegroundColor = ConsoleColor.White; } int lastCount = route.Count; while ( route.Count < graph.Count ) { int vIndex = ChooseNext( route ); route.Insert( vIndex, ChooseIndex( route, vIndex ) ); lastCount = route.Count; if ( Improver != null ) Improver.Improve( route, false ); if ( printProgress ) { Console.CursorLeft = 10; Console.Write( "{0}/{1} - {2} ", route.Count, graph.Count, route.Length ); } } if ( printProgress ) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine( "\n{0} search complete", GetType().Name ); Console.ForegroundColor = ConsoleColor.White; } return route; }
public override bool Iterate(Route route) { bool improved = false; bool cont; do { cont = false; foreach (HillClimbSearcher searcher in Searchers) { bool repeat; do { repeat = searcher.Iterate(route); cont |= repeat; } while (repeat); } improved |= cont; } while (cont); return improved; }
private static Route RunSearch( Graph graph, ISearcher searcher, Route route = null, bool quiet = false ) { if ( searcher is HillClimbSearcher && route != null ) { route = new Route( route ); _stopwatch.Restart(); ( (HillClimbSearcher) searcher ).Improve( route, !quiet ); _stopwatch.Stop(); } else { _stopwatch.Restart(); route = searcher.Search( graph, !quiet ); _stopwatch.Stop(); } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine( "Search time: {0}ms", _stopwatch.ElapsedMilliseconds ); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine( route.ToString() ); return route; }
protected override int ChooseNext( Route route ) { if ( route.Count == 0 ) return 0; int best = -1; int score = 0; _lastIndex = 0; for ( int i = route.Count; i < route.Graph.Count; ++i ) { int val = route.GetFromSelectionBuffer( i ); int minDist = Int32.MaxValue; int minIndex = 0; for ( int j = 0; j < route.Count; ++j ) { int dist = route.Graph[val, route[j]] + route.Graph[val, route[j + 1]]; if ( dist < minDist ) { minDist = dist; minIndex = j; } } if ( minDist > score ) { best = i; score = minDist; _lastIndex = minIndex; } } return best; }
public override bool Iterate( Route route ) { int bestStart = 0; int bestCount = 0; int bestScore = 0; int mid = route.Count / 2; for ( int i = 0; i < route.Count; ++i ) { int s0 = route[ i ]; int s1 = route[ i - 1 ]; for ( int c = 2; c < mid; ++c ) { int e0 = route[ i + c - 1 ]; int e1 = route[ i + c ]; int orig = route.Graph[ s0, s1 ] + route.Graph[ e0, e1 ]; int next = route.Graph[ s0, e1 ] + route.Graph[ e0, s1 ]; int score = orig - next; if ( score > bestScore ) { bestStart = i; bestCount = c; bestScore = score; } } } if ( bestCount > 0 ) { route.Reverse( bestStart, bestCount ); return true; } return false; }
public abstract bool Iterate( Route route );
protected override int ChooseIndex( Route route, int vIndex ) { return 0; }
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; }
protected abstract int ChooseIndex( Route route, int vIndex );
public BestestFirstSearch( HillClimbSearcher improver = null ) : base(improver) { _testRoute = null; }
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); }
protected virtual double FindFitness(Route route) { return route.Length * (double) Math.Abs(route.Count - route.Graph.Count) / route.Graph.Count; }
public BetterRouteFoundEventArgs(Route route) { Route = route; }
protected abstract int ChooseNext( Route route );
public int CalculateShortestDistance(Route route) { return _routes.FirstOrDefault(x => x.Key.Equals(route)).Value; }
public override bool Iterate(Route route) { throw new NotImplementedException(); }