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 );
        }
Пример #3
0
        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;
        }
Пример #9
0
 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();
 }