Beispiel #1
0
        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);
        }
Beispiel #2
0
        public static Route CreateRandom(Graph graph, Random rand)
        {
            Route route = new Route(graph);

            for (int i = 0; i < graph.Count; ++i)
            {
                route.AddEnd(rand.Next(i, graph.Count));
            }
            return(route);
        }
        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 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);
        }