public RuleTableCountStatesRule(string name, CANeighborhood neighborhood, RuleSymmetry symmetry, int states, Dictionary <string, int> ruleDictionary) { RuleDictionary = ruleDictionary; Neighborhood = neighborhood; Symmetry = symmetry; NumStates = states; Name = name; }
public CAThenMove(CANeighborhood neighborhood, List <double> moveProbs, double probability) : base(CAAction.Move, probability) { this.Neighborhood = neighborhood; this.MoveProbs = moveProbs; var temp = MoveProbs.Select(x => x * (1 / MoveProbs.Sum())).ToList(); this.MoveProbsModified = new List <double>() { temp[0] }; for (int i = 1; i < temp.Count; i++) { this.MoveProbsModified.Add(temp[i] + this.MoveProbsModified[i - 1]); } }
public static void ChemicalEquilibrium(ValueTuple <ushort, ushort, ushort> dimensions, List <List <double> > probabilities, string savePath, ValueTuple <ulong, double, double> convergeanceConditions, CASettings settings = null) { List <(string, dynamic)> stateProperties = new List <(string, dynamic)>(); for (int i = 0; i < probabilities.Count; i++) { if (probabilities[i].Count != (probabilities.Count - 1)) { throw new Exception("Each state must include a probability of conversion to every other state (NOT its own)"); } stateProperties.Add(("state", (ushort)i)); } var noneNeighborhood = new CANeighborhood(CANeighborhoodType.None); var localTarget = new CATarget(CAScale.Local, CAEntityType.Agent, noneNeighborhood); CA ca = new CA(dimensions, GridShape.Square); if (settings != null) { ca.Settings = settings; } else { ca.Settings = new CASettings { CopyFormat = CACopyFormat.Reference, StateColorMap = StaticMethods.GetColors(probabilities.Count), /*StoreChangeCounts = true,*/ StoreCounts = true, Subprocessing = false, StoreTransitions = true }; } ca.Settings.States = (ushort)probabilities.Count; for (int i = 0; i < probabilities.Count; i++) { ca.AddAgents((1.0 / probabilities.Count), (ushort)i, true); int val = 0; CAIf stateif = new CAIf("state", CATargetType.All, localTarget, CAEquality.Equal_to, stateProperties[i]); for (int j = 0; j < probabilities.Count; j++) { if (i == j) { continue; } CAThenChange changeThen = new CAThenChange(localTarget, "state", CAOperator.Equal, (ushort)j, probabilities[i][val]); CARule changeRule = new CARule(new List <CAIf> { stateif }, new List <CAThen> { changeThen }); ca.AddRule(changeRule); val++; } } CAExitCondition exit = new CAExitConditionConvergeance(convergeanceConditions.Item1, convergeanceConditions.Item2, convergeanceConditions.Item3); ca.CreateExitCondition(exit); DateTime start = DateTime.Now; //bool alive = true; Console.WriteLine("Every iteration, the CA will check that the population counts have changed by less than " + (convergeanceConditions.Item2 > 1? ((int)convergeanceConditions.Item2).ToString() + " cells":(convergeanceConditions.Item2 * 100).ToString() + "%") + " (for a single state)."); Console.WriteLine("It will then check for >" + convergeanceConditions.Item1 + " iterations, then " + (convergeanceConditions.Item3 > 1 ? ((int)convergeanceConditions.Item3).ToString() + " iterations" : (convergeanceConditions.Item3 * 100).ToString() + "%") + " of the total iterations, where the previous predicate is true (consecutively)."); Console.WriteLine("It will automatically end at that time, but you can exit early by pressing Escape. Your data up to that point will be saved."); Console.WriteLine("Press Enter to begin."); Console.ReadKey(); DateTime now = DateTime.Now; Task output = Task.Factory.StartNew(() => { while (!ca.Exit && !(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)) { ca.Run(); Console.Write("\rIteration {0}, Counts: {1}", ca.Iteration, String.Join(", ", ca.CurrentCounts) + " "); } Console.WriteLine(""); }); output.Wait(); Console.WriteLine("Task complete after: " + (DateTime.Now - now).TotalSeconds + " seconds"); var probString = probabilities.Select(x => x.Select(y => y.ToString()).ToList()).ToList(); for (int i = 0; i < probString.Count; i++) { probString[i].Insert(0, i.ToString()); } // save data List <List <string> > header = new List <List <string> >() { new List <string> { now.ToString("o") }, new List <string> { "Chemical Equilibrium" }, new List <string> { "Probabilities" } }; header.AddRange(probString); ca.Save(header, ca.ListSaveProperties(), savePath + System.IO.Path.DirectorySeparatorChar + start.ToString("o").Replace(':', '.') + " Iteration " + ca.Iteration + " Data.csv"); Console.WriteLine("Data saved to: " + savePath + System.IO.Path.DirectorySeparatorChar + start.ToString("o").Replace(':', '.') + " Iteration " + ca.Iteration + " Data.csv"); Console.WriteLine(); Console.WriteLine("Enter Y to save image, and anything else to skip."); bool saveImage = false; var key = Console.ReadLine(); if (key.ToLower().Equals("y")) { saveImage = true; } else { Console.WriteLine("Are you sure? Enter Y to save image, and anything else to skip."); key = Console.ReadLine(); if (key.ToLower().Equals("y")) { saveImage = true; } } if (saveImage) { var image = StaticMethods.MakeImage(ca); string filename = savePath + System.IO.Path.DirectorySeparatorChar + start.ToString("o").Replace(':', '.') + " Iteration " + ca.Iteration + " Image.bmp"; image.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp); Console.WriteLine("Saved to {0}.", filename); } Console.WriteLine("Complete. Press any key to exit."); Console.ReadKey(); }
// add target. get source at runtime public CALocationRelative(CANeighborhood Neighborhood) : base(CACreationLocationType.Relative) { this.Neighborhood = Neighborhood; }