示例#1
0
        public static Ant RunMMAS(Graph graph, Parameters parameters, UInt32 iterations)
        {
            var greedySolution = CreateSolutionNN(graph);
            var greedyCost     = graph.CalculateRouteLength(greedySolution.visited);

            var initialLimits = CalcTrailLimitsMMAS(parameters, graph.dimension, greedyCost);
            var minPheromone  = initialLimits.Item1;
            var maxPheromone  = initialLimits.Item2;

            PheromoneMemory pheromone = new PheromoneMemory(graph.dimension, maxPheromone);

            double[] heuristic = new double[graph.dimension * graph.dimension];

            foreach (var distance in graph.edgeWeight)
            {
                for (int i = 0; i < graph.dimension; i++)
                {
                    for (int j = 0; j < graph.dimension; j++)
                    {
                        heuristic[j + (graph.dimension * i)] = (1 / Math.Pow(graph.edgeWeight[i, j], parameters.beta));
                    }
                }
            }

            Ant[] ants = new Ant[parameters.antsCount];
            for (int i = 0; i < parameters.antsCount; i++)
            {
                ants[i] = new Ant();
            }
            Ant bestAnt = new Ant();

            for (UInt32 iteration = 0; iteration < iterations; ++iteration)
            {
                foreach (Ant ant in ants)
                {
                    ant.Initialize(graph.dimension);
                    var startNode = GetRandomUInt32(0, graph.dimension - 1);
                    ant.Visit(startNode);
                    for (UInt32 j = 1; j < graph.dimension; ++j)
                    {
                        moveAntMMAS(graph, pheromone, heuristic, ant);
                    }
                    ant.cost = graph.CalculateRouteLength(ant.visited);
                }

                var  iterationBest = ants[0];
                bool newBestFound  = false;

                foreach (Ant ant in ants)
                {
                    if (ant.cost < bestAnt.cost)
                    {
                        bestAnt      = ant;
                        newBestFound = true;

                        Console.WriteLine("New best solution found with the cost: {0} at iteration {1}", bestAnt.cost, iteration);
                    }

                    if (ant.cost < iterationBest.cost)
                    {
                        iterationBest = ant;
                    }
                }

                if (newBestFound)
                {
                    var limits = CalcTrailLimitsMMAS(parameters, graph.dimension, bestAnt.cost);
                    minPheromone = limits.Item1;
                    maxPheromone = limits.Item2;
                }

                pheromone.EvaporateFromAll(parameters.GetEvaporationRate(), minPheromone);

                var    updateAnt    = iterationBest;
                double deposite     = 1.0 / updateAnt.cost;
                var    previousNode = updateAnt.visited[updateAnt.visited.Count - 1];
                foreach (var node in updateAnt.visited)
                {
                    pheromone.Increase(previousNode, node, deposite, maxPheromone, graph.isSymetric);
                    previousNode = node;
                }
            }
            return(bestAnt);
        }
示例#2
0
        public static UInt32 moveAntMMAS(Graph graph, PheromoneMemory pheromone, double [] heuristic, Ant ant)
        {
            var    dimension   = graph.dimension;
            var    currentNode = ant.visited[ant.visited.Count - 1];
            UInt32 offset      = currentNode * dimension;

            UInt32 [] candList     = new UInt32 [MaxCandListSize];
            UInt32    candListSize = 0;

            for (int i = 0; i < graph.dimension; i++)
            {
                if (!ant.IsVisited((UInt32)i))
                {
                    candList[candListSize] = (UInt32)i;
                    ++candListSize;
                }
            }

            UInt32 chosenNode = currentNode;

            if (candListSize > 0)
            {
                double[] productsPrefixSum = new double[MaxCandListSize];
                double   total             = 0;
                for (UInt32 j = 0; j < candListSize; ++j)
                {
                    var node    = candList[j];
                    var product = pheromone.Get(currentNode, node) * heuristic[offset + node];
                    total += product;
                    productsPrefixSum[j] = total;
                }

                chosenNode = candList[candListSize - 1];

                var r = GetRandomDouble() * total;
                for (UInt32 i = 0; i < candListSize; ++i)
                {
                    if (r < productsPrefixSum[i])
                    {
                        chosenNode = candList[i];
                        break;
                    }
                }
            }
            else
            {
                double maxProduct = 0;
                for (UInt32 node = 0; node < dimension; ++node)
                {
                    if (!ant.IsVisited(node))
                    {
                        var product = pheromone.Get(currentNode, node) * heuristic[offset + node];
                        if (product > maxProduct)
                        {
                            maxProduct = product;
                            chosenNode = node;
                        }
                    }
                }
            }

            ant.Visit(chosenNode);
            return(chosenNode);
        }