예제 #1
0
        public void Forage(IAntColonyContext context)
        {
            if (context.Steps.Count == 0)
            {
                throw new ArgumentOutOfRangeException("No steps provided");
            }

            ICollection <IStep> availableSteps = context.Steps;
            Int32 randomIndex = randomInstance.Next(availableSteps.Count());

            // Set the initial start point
            IStep currentStep = default(IStep);

            if (availableSteps.Count > 0)
            {
                currentStep = availableSteps.ElementAt(randomIndex);

                // Process each step until no steps remain
                availableSteps = currentStep.Available(context).OfType <IStep>().ToList();
                while (availableSteps.Count() > 0)
                {
                    IStep nextStep = SelectNext(availableSteps);
                    (context.Path as INodePath).Add(nextStep, nextStep.Score);
                    currentStep    = nextStep;
                    availableSteps = currentStep.Available(context).OfType <IStep>().ToList();
                }
                context.Path.Validate(context);
                //Console.WriteLine("Path: {0}: {1}", context.Path.Score,
                //    (((INodePath) context.Path).Steps != null
                //        ? string.Join(",", ((INodePath) context.Path).Steps.Select(e => e.StepName))
                //        : ""));
            }
        }
 public IEnumerable <IPheremoneKey> Available(IAntColonyContext context)
 {
     foreach (IPheremoneKey key in Edges.Where(e => !context.Path.Contains(e.StartStep.StepName.Equals(StepName) ? e.EndStep : e.StartStep)).OfType <IPheremoneKey>())
     {
         yield return(key);
     }
 }
예제 #3
0
 public IEnumerable <IPheremoneKey> Available(IAntColonyContext context)
 {
     foreach (IPheremoneKey key in context.Steps.Where(s => !((context.Path as INodePath).Steps.OfType <IStep>().Any(k => k.Equals(s)))).OfType <IPheremoneKey>())
     {
         yield return(key);
     }
 }
예제 #4
0
        public void Validate(object contextObject)
        {
            IAntColonyContext context = contextObject as IAntColonyContext;

            if (Steps.Count != (context.Steps.Count - 1))
            {
                InvalidPath = true;
            }
        }
예제 #5
0
        private void InitialisePathPheremones(IAntColonyContext context, IDictionary <IEdge, Pheremone> map, decimal initialPheremoneLevel)
        {
            AntColonyContext c = context as AntColonyContext;

            foreach (IStep step in c.Steps)
            {
                //if (!map.ContainsKey(step))
                //    map[step] = new Pheremone(initialPheremoneLevel);
            }
        }
예제 #6
0
 /// <summary>
 /// Initialise each of the ants.
 /// <para>At this point is only required to make a clone
 /// of the InitialContext for each of the ants to use</para>
 /// </summary>
 /// <param name="context">The initial context</param>
 public void InitialiseAnts(IAntColonyContext context)
 {
     InitialContext = context;
     Contexts       = new List <IAntColonyContext>();
     for (int i = 0; i < NumberOfAnts; ++i)
     {
         IAntColonyContext c = context.Clone() as IAntColonyContext;
         c.Id = i + 1;
         Contexts.Add(c);
     }
 }
예제 #7
0
        /// <summary>
        /// Set each of the ants out on it's forage track,
        /// and wait for them all to return.
        /// <para>Select the best path from all of paths travelled by
        /// the ants and drop pheremones on that path.</para>
        /// <para>Decay the pheremone level in all paths in the pheremone map</para>
        /// <para>Repeat the above process for the required number of iterations</para>
        /// <para>Return the result in the InitialContext.BestPaths property</para>
        /// </summary>
        public void RunAnts()
        {
            const int MaxRepetitions = 2000;
            Int32     sameScore      = 0;

            InitialisePheremones();
            ICollection <IPath> paths = new List <IPath>();

            for (int i = 0; i < Iterations; ++i)
            {
                ICollection <TAnt> ants = new List <TAnt>(NumberOfAnts);
                for (int a = 0; a < NumberOfAnts; ++a)
                {
                    IAntColonyContext c = Contexts[a];
                    c.Reset();
                    TAnt ant = new TAnt();
                    ant.Initialise(a * i + 1, PheremoneMap, InitialPheremoneLevel);
                    ant.Context = c;
                    ants.Add(ant);
                }

                ants.AsParallel().ForEach(a => a.Forage(a.Context));

                ICollection <IPath> bestPaths = DetermineBestPaths();
                // If new paths are more efficient than old paths save them
                if (paths.Count() == 0 || (paths.First().Score > bestPaths.First().Score))
                {
                    paths     = new List <IPath>(bestPaths);
                    sameScore = 0;
                }
                // If same score merge the set of paths
                else if (paths.First().Score == bestPaths.First().Score)
                {
                    paths = paths.Union(bestPaths).Distinct().ToList();
                }

                // TODO: Make the exit condition a predicate instead
                if (sameScore++ > MaxRepetitions)
                {
                    Console.WriteLine(string.Format("Exiting due to repetition of same score on iteration {0}", i));
                    break;
                }
                //Console.WriteLine("Iteration {0}: Score: {1} Returned: {2}", i, paths.First().Score, bestPaths.First().Score);

                // Manage the pheremone levels after the iteration completes
                PheremoneMap.ForEach(e => e.Value.Decay(EvaporationRate));
                if (paths.First().Score < decimal.MaxValue)
                {
                    paths.ForEach(p => DepositPheremones(PheremoneMap, (dynamic)p));
                }
            }
            InitialContext.BestPaths = paths.OfType <IPath>().ToList();
        }
예제 #8
0
        public void Forage(IAntColonyContext context)
        {
            if (context.Steps.Count == 0)
            {
                throw new ArgumentOutOfRangeException("No steps provided");
            }

            ICollection <IStep> availableSteps = context.Steps;
            Int32 randomIndex = randomInstance.Next(availableSteps.Count());

            // Set the initial start point
            IStep currentStep = default(IStep);

            if (availableSteps.Count > 0)
            {
                //Console.WriteLine(string.Format("Initial random index = {0}", randomIndex));
                currentStep = availableSteps.ElementAt(randomIndex);
                //availableSteps.Remove(currentStep);
            }

            // Process each step until no steps remain
            ICollection <IEdge> availableEdges = currentStep.Available(context).OfType <IEdge>().ToList();

            while (availableEdges.Count() > 0)
            {
                IEdge nextEdge = SelectNext(availableEdges) as IEdge;
                IStep nextStep;
                if (nextEdge.StartStep.Equals(currentStep))
                {
                    nextStep = nextEdge.EndStep;
                }
                else
                {
                    nextStep = nextEdge.StartStep;
                }
                (context.Path as IPathPath).Add(currentStep, nextStep, nextEdge.Score);
                currentStep    = nextStep;
                availableEdges = currentStep.Available(context).OfType <IEdge>().ToList();
            }
            context.Path.Validate(context);
            //Console.WriteLine(string.Format("Path: {0} {1} {2}", context.Path.Score, context.Path.Edges.First().StartStep.StepName, string.Join(",", context.Path.Edges.Select(e => e.EndStep.StepName))));
        }
        //#region IComparable<IEdge<int>> Members

        //public int CompareTo(IEdge<int> other)
        //{
        //    if (other == null)
        //        return -1;
        //    if (Score.CompareTo(other.Score) != 0)
        //        return Score.CompareTo(other.Score);
        //    if (StartStep.CompareTo(other.StartStep) != 0)
        //        return Score.CompareTo(other.StartStep);
        //    return Score.CompareTo(other.EndStep);
        //}

        //#endregion

        #region IPheremoneKey Members

        public IEnumerable <IPheremoneKey> Available(IAntColonyContext context)
        {
            return(EndStep.Available(context));
        }