Beispiel #1
0
        private TSPSolution getShortestTour()
        {
            double lowestCost = Double.PositiveInfinity;
            Ant    lowestAnt  = null;

            foreach (Ant ant in ants)
            {
                if (ant.getFinalTourLength(Cities) < lowestCost)
                {
                    lowestCost = ant.getFinalTourLength(Cities);
                    lowestAnt  = ant;
                }
            }
            if (lowestAnt == null)
            {
                return(null);
            }
            return(new TSPSolution(indexToCities(Cities, lowestAnt.pathSoFar)));
        }
        private Edge NextEdge(Ant ant)
        {
            double c = 0;
            double r = random.NextDouble();

            Vertex vertex = ant.visitedVertices.Peek();

            foreach (Edge e in vertex.neighbors)
            {
                if (!ant.visitedVertices.Contains(e.vertex2))
                {
                    c += Probability(ant, e);
                    if (c >= r)
                    {
                        return(e);
                    }
                }
            }
            return(null);
        }
 private void AntPath(Ant ant)
 {
     counter = 0;
     AntPathRecurring(ant, ant.startVertex);
 }
        public void antSolve()
        {
            timer = new Stopwatch();
            timer.Start();

            //BASF = Best Ant So Far
            Ant BASF, bestAnt, worstAnt;
            Edge[,] matrix = generateCostMatrix();

            do
            {
                BASF = new Ant(ref matrix);
            } while (!(BASF.IsComplete));

            //I found that these were good values.
            double MIN_IMPROVEMENT = .70;
            int MAX_REDUNDANT_ITERATIONS = 25;
            int redundant_iterations = 0;
            while (redundant_iterations < MAX_REDUNDANT_ITERATIONS)
            {
                do
                {
                    bestAnt = new Ant(ref matrix);
                } while (!bestAnt.IsComplete);
                worstAnt = bestAnt;
                //send out ants!
                //With only two ants, two sets of edges will be either increased or decayed. Edges occuring in both solutions will be slightly decremented.
                for (int j = 1; j < 2; j++)
                {
                    Ant ant = new Ant(ref matrix);
                    if (ant.IsComplete)
                    {
                        if (ant.TotalCost < bestAnt.TotalCost)
                            bestAnt = ant;
                        else if (ant.TotalCost > worstAnt.TotalCost)
                            worstAnt = ant;
                    }

                }

                bestAnt.updatePheromones(false);
                worstAnt.updatePheromones(true);
                //improvement represents the ratio of this ant's journey to the current best.
                double improvement = bestAnt.TotalCost / BASF.TotalCost;
                if (improvement < 1)
                    BASF = bestAnt;
                if (improvement > MIN_IMPROVEMENT)
                    redundant_iterations++;
            }

            // call this the best solution so far.  bssf is the route that will be drawn by the Draw method.
            Route = new ArrayList(Cities.Length);
            for (int i = 0; i < BASF.Route.Count; i++)
                Route.Add(Cities[BASF.Route[i]]);
            bssf = new TSPSolution(Route);
            // update the cost of the tour.

                TimeSpan ts = timer.Elapsed;

            // do a refresh.

            Program.MainForm.tbCostOfTour.Text = " " + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString();
            Program.MainForm.Invalidate();
        }
        public void antSolve()
        {
            timer = new Stopwatch();
            timer.Start();

            //BASF = Best Ant So Far
            Ant BASF, bestAnt, worstAnt;

            Edge[,] matrix = generateCostMatrix();

            do
            {
                BASF = new Ant(ref matrix);
            } while (!(BASF.IsComplete));

            //I found that these were good values.
            double MIN_IMPROVEMENT          = .70;
            int    MAX_REDUNDANT_ITERATIONS = 25;
            int    redundant_iterations     = 0;

            while (redundant_iterations < MAX_REDUNDANT_ITERATIONS)
            {
                do
                {
                    bestAnt = new Ant(ref matrix);
                } while (!bestAnt.IsComplete);
                worstAnt = bestAnt;
                //send out ants!
                //With only two ants, two sets of edges will be either increased or decayed. Edges occuring in both solutions will be slightly decremented.
                for (int j = 1; j < 2; j++)
                {
                    Ant ant = new Ant(ref matrix);
                    if (ant.IsComplete)
                    {
                        if (ant.TotalCost < bestAnt.TotalCost)
                        {
                            bestAnt = ant;
                        }
                        else if (ant.TotalCost > worstAnt.TotalCost)
                        {
                            worstAnt = ant;
                        }
                    }
                }

                bestAnt.updatePheromones(false);
                worstAnt.updatePheromones(true);
                //improvement represents the ratio of this ant's journey to the current best.
                double improvement = bestAnt.TotalCost / BASF.TotalCost;
                if (improvement < 1)
                {
                    BASF = bestAnt;
                }
                if (improvement > MIN_IMPROVEMENT)
                {
                    redundant_iterations++;
                }
            }

            // call this the best solution so far.  bssf is the route that will be drawn by the Draw method.
            Route = new ArrayList(Cities.Length);
            for (int i = 0; i < BASF.Route.Count; i++)
            {
                Route.Add(Cities[BASF.Route[i]]);
            }
            bssf = new TSPSolution(Route);
            // update the cost of the tour.

            TimeSpan ts = timer.Elapsed;

            // do a refresh.


            Program.MainForm.tbCostOfTour.Text  = " " + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = ts.TotalSeconds.ToString();
            Program.MainForm.Invalidate();
        }
Beispiel #6
0
        public void doCircut(Ant ant)
        {
            ant.visitCity(rand.Next(0, Cities.Length));
            for (int i = 0; i < Cities.Length - 1; i++)
            {
                if (rand.NextDouble() < RANDOM_CHANCE)
                {
                    int t = rand.Next(Cities.Length - ant.getCurrentCity()); // random town
                    int j = -1;
                    for (int k = 0; k < Cities.Length; k++)
                    {
                        if (!ant.citiesVisited[k])
                        {
                            j++;
                        }
                        if (j == t)
                        {
                            ant.visitCity(k);
                            break;
                        }
                    }
                }

                double[] probs = new double[Cities.Length];
                double   denom = 0.0;

                for (int j = 0; j < Cities.Length; j++)
                {
                    if (ant.citiesVisited[j])
                    {
                        probs[j] = 0.0;
                    }
                    else
                    {
                        probs[j] = getProbability(ant.getCurrentCity(), j);
                    }
                    denom += probs[j];
                }

                if (denom == 0)
                {
                    ant = new Ant(Cities.Length);
                    doCircut(ant);
                    if (ant.pathSoFar.Count < Cities.Length)
                    {
                        finishPath(ant);
                        return;
                    }
                    return;
                }
                for (int j = 0; j < Cities.Length; j++)
                {
                    probs[j] /= denom;
                }
                double r     = rand.NextDouble();
                double total = 0.0;
                for (int j = 0; j < Cities.Length; j++)
                {
                    total += probs[j];
                    if (total >= r)
                    {
                        ant.visitCity(j);
                        break;
                    }
                }
            }
            if (ant.pathSoFar.Count < Cities.Length)
            {
                finishPath(ant);
                return;
            }
        }
Beispiel #7
0
 /*
  * Clears out the ant's path.
  * The ant's new path is then started at a random city.
  */
 private void ResetAnt(Ant ant)
 {
     ant.Path.Clear();
     ant.Visited.Clear();
     ant.Add(random.Next(0, Cities.Length));
 }
Beispiel #8
0
        public string[] fancySolveProblem()
        {
            string[]  results = new string[3];
            int       count   = 0;
            Stopwatch timer   = new Stopwatch();

            Ant[] ants = new Ant[Cities.Length];
            //Initialize with empty ants
            for (int i = 0; i < Cities.Length; i++)
            {
                ants[i] = new Ant();
                ants[i].Add(i);
            }

            distances = CalculateInitialMatrix();

            pheromones = new double[Cities.Length, Cities.Length];
            for (int i = 0; i < Cities.Length; i++)
            {
                for (int j = 0; j < Cities.Length; j++)
                {
                    pheromones[i, j] = 1;
                }
            }

            int iterations = 0;

            timer.Start();

            /*
             * While we are not out of time and still seeing changes,
             * The ants all select the best edge out of current city.
             * This is done using the distance and pheromone of the edge.
             * When a completed tour is found, it is compared to the BSSF.
             * If the tour is better the BSSF is updated.
             * The existing, older pheromones fade by a constant factor,
             * and additional pheromone is placed on the new tour.
             * After this an ant with a completed tour is reset.
             */
            while (timer.Elapsed.TotalMilliseconds < time_limit && iterations < ITERATION_THRESHOLD)
            {
                for (int i = 0; i < Cities.Length; i++)
                {
                    for (int j = 0; j < Cities.Length; j++)
                    {
                        if (ants[j].Count == Cities.Length)
                        {
                            if (Cities[ants[j].Path[ants[j].Count - 1]].costToGetTo(Cities[ants[j].Path[0]]) != double.PositiveInfinity)
                            {
                                TSPSolution potentialSolution = GenerateRoute(ants[j].Path);
                                double      costOfRoute       = potentialSolution.costOfRoute();
                                if (bssf == null || costOfRoute < costOfBssf())
                                {
                                    iterations = 0;
                                    bssf       = potentialSolution;
                                    count++;
                                }
                                FadePheromone();
                                DropPheromone(ants[j], costOfRoute);
                            }
                            ResetAnt(ants[j]);
                        }
                        TakeNextEdge(ants[j]);
                    }
                }
                iterations++;
            }

            timer.Stop();

            results[COST]  = costOfBssf().ToString();
            results[TIME]  = timer.Elapsed.ToString();
            results[COUNT] = count.ToString();

            Console.WriteLine("Ant Colony Size: " + Cities.Length + " Random: " + Seed + " Path: " + costOfBssf().ToString() + " Time: " + timer.Elapsed.ToString());


            return(results);
        }
Beispiel #9
0
        public void groupTSP()
        {
            // start our timer
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            // constants used in heuristics
            const int    ITERATIONS = 50;
            const double Q0         = 0.9;
            const double BETA       = 50.0;
            const double ALPHA      = 0.1;

            // get cost from nearest neighbor, used in our heuristic
            greedy();

            double nnCost = costOfBssf();

            // our fastest ant through all the iterations
            Ant    bestAnt  = null;
            double bestCost = Double.PositiveInfinity;

            // initialize pheramone level matrix
            double[,] pheromoneLevels = new double[Cities.Length, Cities.Length];
            for (int i = 0; i < Cities.Length; i++)
            {
                for (int j = 0; j < Cities.Length; j++)
                {
                    pheromoneLevels[i, j] = 1.0 / Cities.Length;
                }
            }

            // start iterations
            for (int h = 0; h < ITERATIONS; h++)
            {
                // our fastest ant in the iteration
                Ant    bestAntIter  = null;
                double bestCostIter = Double.PositiveInfinity;

                // initialize ants
                List <Ant> ants = new List <Ant>();
                for (int i = 0; i < Cities.Length; i++)
                {
                    ants.Add(new Ant(Cities.Length, i));
                }

                // iterate through each time step
                for (int i = 0; i < Cities.Length - 1; i++)
                {
                    // determine each ants next move
                    List <Ant> remainingAnts = new List <Ant>(ants);
                    foreach (Ant ant in remainingAnts)
                    {
                        int    nextCity     = -1;
                        double nextDistance = Double.PositiveInfinity;

                        Random random = new Random();
                        double q      = random.NextDouble();
                        if (q < Q0)
                        {
                            // select next city based on distance / pheramone only
                            double bestScore = Double.NegativeInfinity;
                            foreach (int city in ant.unvisited)
                            {
                                double distance = Cities[ant.curCity].costToGetTo(Cities[city]);
                                double score    = pheromoneLevels[ant.curCity, city] * Math.Pow(1 / distance, BETA);
                                if (score > bestScore)
                                {
                                    nextCity     = city;
                                    bestScore    = score;
                                    nextDistance = distance;
                                }
                            }
                        }
                        else
                        {
                            // select city randomly with different weights given to each city based on distance / pheramone
                            double runningTotal = 0.0;
                            double randomValue  = random.NextDouble();

                            // get sum of scores
                            double summedScores = 0.0;
                            foreach (int city in ant.unvisited)
                            {
                                double distance = Cities[ant.curCity].costToGetTo(Cities[city]);
                                summedScores += pheromoneLevels[ant.curCity, city] * Math.Pow(1 / distance, BETA);
                            }

                            // determine probability for each city
                            foreach (int city in ant.unvisited)
                            {
                                double distance = Cities[ant.curCity].costToGetTo(Cities[city]);
                                runningTotal += (pheromoneLevels[ant.curCity, city] * Math.Pow(1 / distance, BETA)) / summedScores;
                                if (runningTotal > randomValue)
                                {
                                    nextCity     = city;
                                    nextDistance = distance;
                                    break;
                                }
                            }
                        }

                        if (nextCity != -1)
                        {
                            // apply local trail updating
                            pheromoneLevels[ant.curCity, nextCity] += (1 - ALPHA) * pheromoneLevels[ant.curCity, nextCity] + ALPHA * (1 / (Cities.Length * nnCost));

                            // add the picked city to the tour
                            ant.tour[ant.curCity] = nextCity;
                            ant.unvisited.Remove(nextCity);
                            ant.curCost += nextDistance;
                            ant.prevCity = ant.curCity;
                            ant.curCity  = nextCity;
                        }
                        else
                        {
                            //deal with stuck ant
                            ants.Remove(ant);
                        }
                    }
                }

                // finalize tours and find best ant
                foreach (Ant ant in ants)
                {
                    // finalize tour
                    ant.tour[ant.curCity] = ant.startCity;
                    ant.curCost          += Cities[ant.curCity].costToGetTo(Cities[ant.startCity]);

                    // check against current best cost
                    if (ant.curCost < bestCostIter)
                    {
                        bestAntIter  = ant;
                        bestCostIter = ant.curCost;
                    }
                }

                if (bestAntIter != null)
                {
                    // apply global trail updating
                    int current = bestAntIter.startCity;
                    do
                    {
                        pheromoneLevels[current, bestAntIter.tour[current]] += (1 - ALPHA) * pheromoneLevels[current, bestAntIter.tour[current]] + ALPHA * (1 / bestCostIter);
                        current = bestAntIter.tour[current];
                    } while (current != bestAntIter.startCity);

                    // see if it is the best ant through all iterations so far
                    if (bestCostIter < bestCost)
                    {
                        bestAnt  = bestAntIter;
                        bestCost = bestCostIter;
                    }
                }
            }

            if (bestAnt != null)
            {
                ArrayList route   = new ArrayList();
                int       curCity = bestAnt.startCity;
                do
                {
                    route.Add(Cities[curCity]);
                    curCity = bestAnt.tour[curCity];
                } while (curCity != bestAnt.startCity);
                bssf = new TSPSolution(route);
            }

            timer.Stop();

            Program.MainForm.tbCostOfTour.Text  = " " + bssf.costOfRoute();
            Program.MainForm.tbElapsedTime.Text = Convert.ToString(timer.Elapsed);

            // do a refresh.
            Program.MainForm.Invalidate();
        }