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); } }
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); } }
public void Validate(object contextObject) { IAntColonyContext context = contextObject as IAntColonyContext; if (Steps.Count != (context.Steps.Count - 1)) { InvalidPath = true; } }
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); } }
/// <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); } }
/// <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(); }
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)); }