//public static T GetTypedValue<T>(CAProperty property)
        //{
        //    dynamic value = property.value;
        //    return value;
        //}

        public static Bitmap MakeImage(CA ca)
        {
            CAGraph    graph    = ca.Graph;
            CASettings settings = ca.Settings;

            // needs to be SVG that returns various types
            if (graph.Shape == GridShape.Square)
            {
                int x = graph.Cells.GetLength(0);
                int y = graph.Cells.GetLength(1);
                int z = graph.Cells.GetLength(2);

                Bitmap bmp = new Bitmap(x, y);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    for (ushort i = 0; i < z; i++)
                    {
                        Bitmap layer = new Bitmap(x, y);
                        for (ushort j = 0; j < x; j++)
                        {
                            for (ushort k = 0; k < y; k++)
                            {
                                var   cell  = graph.GetCell(new ValueTuple <ushort, ushort, ushort>(j, k, i));
                                Color color = Color.Black;
                                if (cell != null)
                                {
                                    if (cell.ContainsAgent())
                                    {
                                        int state = cell.Agent.GetStateProperty();
                                        if (settings.StateColorMap.Count >= state)
                                        {
                                            color = settings.StateColorMap[state];
                                        }
                                    }
                                }
                                layer.SetPixel(j, k, color);
                            }
                        }
                        g.DrawImage(layer, new Point(0, 0));
                    }
                }
                return(bmp);
            }
            else
            {
                throw new Exception("Graph shape not expected.");
            }
        }
Exemple #2
0
        //List<double> times = new List<double>();
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraph(CA parent, ValueTuple <ushort, ushort, ushort> size, GridShape shape) : base(CAEntityType.Graph)
        {
            this.Parent = parent;
            this.Shape  = shape;
            AgentCells  = new List <ValueTuple <ushort, ushort, ushort> >();
            Updates     = new List <ValueTuple <ushort, ushort, ushort> >();
            Dimensions  = new ValueTuple <ushort, ushort, ushort>(size.Item1, size.Item2, size.Item3);
            Cells       = new CAGraphCell[size.Item1, size.Item2, size.Item3];
            for (ushort i = 0; i < Cells.GetLength(0); i++)
            {
                for (ushort j = 0; j < Cells.GetLength(1); j++)
                {
                    for (ushort k = 0; k < Cells.GetLength(2); k++)
                    {
                        Cells[i, j, k] = new CAGraphCell(this, new ValueTuple <ushort, ushort, ushort>(i, j, k));
                    }
                }
            }
        }
Exemple #3
0
 public CAGraph(CA parent, ValueTuple <ushort, ushort, ushort> size, GridShape shape, List <ValueTuple <ushort, ushort, ushort> > agents, CAGraphCell[,,] cells, Dictionary <string, dynamic> properties) : base(CAEntityType.Graph, properties)
 {
     Parent     = parent;
     Shape      = shape;
     AgentCells = agents.ConvertAll(x => new ValueTuple <ushort, ushort, ushort>(x.Item1, x.Item2, x.Item3));
     Updates    = new List <ValueTuple <ushort, ushort, ushort> >();
     Dimensions = new ValueTuple <ushort, ushort, ushort>(size.Item1, size.Item2, size.Item3);
     Cells      = new CAGraphCell[size.Item1, size.Item2, size.Item3];
     for (ushort i = 0; i < size.Item1; i++)
     {
         for (ushort j = 0; j < size.Item2; j++)
         {
             for (ushort k = 0; k < size.Item3; k++)
             {
                 //if(i == 500 && j == 500)
                 //{
                 //    Console.WriteLine();
                 //}
                 Cells[i, j, k] = cells[i, j, k].Copy(this);
             }
         }
     }
 }
        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();
        }
        public static void DLA(ushort x, ushort y, ushort z, string path, bool useRings = false)
        {
            DateTime start  = DateTime.Now;
            bool     alive  = true;
            var      state0 = ("state", (ushort)0);
            var      state1 = ("state", (ushort)1);

            CAIf       moveIf   = new CAIf("state", CATargetType.All, new CATarget(CAScale.Local, CAEntityType.Agent, new CANeighborhood(CANeighborhoodType.None)), CAEquality.Equal_to, state0);
            CAThenMove moveThen = new CAThenMove(new CANeighborhood(CANeighborhoodType.Edge), new List <double> {
                0.25, 0.25, 0.25, 0.25
            }, 1);
            CARule moveRule = new CARule(new List <CAIf> {
                moveIf
            }, new List <CAThen> {
                moveThen
            });


            CA  ca     = new CA(new ValueTuple <ushort, ushort, ushort>(x, y, z), GridShape.Square);
            var center = new Dictionary <string, dynamic>
            {
                { "state", (ushort)1 }
            };

            ca.AddAgents(new List <ValueTuple <Dictionary <string, dynamic>, ValueTuple <ushort, ushort, ushort> > > {
                new ValueTuple <Dictionary <string, dynamic>, ValueTuple <ushort, ushort, ushort> >(center, new ValueTuple <ushort, ushort, ushort>(Convert.ToUInt16(x / 2), Convert.ToUInt16(y / 2), Convert.ToUInt16(z / 2)))
            });
            ca.Settings.StateColorMap = new List <Color> {
                Color.Red, Color.White
            };
            ca.Settings.Subprocessing = true;
            ca.Settings.CopyFormat    = CACopyFormat.Reference;
            var edge = new Dictionary <string, dynamic>
            {
                { "state", (ushort)0 }
            };

            var minDim  = Math.Min(x, y);
            int percent = 100;

            //var minDouble = 1.0;
            //var minShift = Math.Max(1.0 / minDim, 0.01);
            //var curDouble = 1.0;
            if (useRings)
            {
                percent = 1;
                //minDouble = Math.Max(10.0 / minDim, 0.01);
                //curDouble = minDouble;
            }

            CAIf         changeIf1     = new CAIf("state", CATargetType.All, new CATarget(CAScale.Local, CAEntityType.Agent, new CANeighborhood(CANeighborhoodType.None)), CAEquality.Equal_to, state0);
            CAIf         changeIf2     = new CAIf("state", CATargetType.Any, new CATarget(CAScale.Regional, CAEntityType.Agent, new CANeighborhood(CANeighborhoodType.Edge)), CAEquality.Equal_to, state1);
            CAThenChange changeThen    = new CAThenChange(new CATarget(CAScale.Local, CAEntityType.Agent, new CANeighborhood(CANeighborhoodType.None)), "state", CAOperator.Equal, (ushort)1, 1);
            var          locationShape = new CALocationShape(CACreationLocationShapeType.Circle, new ValueTuple <ushort, ushort, ushort>(x, y, z), Math.Min(((double)percent / 100.0), 1.0));
            CAThenCreate changeCreate  = new CAThenCreate(locationShape, (ushort)0, 1); // this adds ~1 GB for 5001
            CARule       changeRule    = new CARule(new List <CAIf> {
                changeIf1, changeIf2
            }, new List <CAThen> {
                changeThen, changeCreate
            });

            if (useRings)
            {
                (changeRule.Thens[1] as CAThenCreate).Failure += ((object source, CreationEventArgs e) =>
                {
                    if (e.Cause == CreationEventArgs.CreationStatus.Failure_AgentExists)
                    {
                        Console.WriteLine("");
                        if (percent == 100)
                        {
                            Console.WriteLine("Outer ring complete.");
                            alive = false;
                        }
                        else
                        {
                            var locPercents = (((e.Location.Item1 - (x / 2.0)) / (x / 2.0)), ((e.Location.Item2 - (y / 2.0)) / (y / 2.0)), ((e.Location.Item3 - (z / 2.0)) / (z / 2.0)));
                            var maxPer = Math.Max(locPercents.Item1, locPercents.Item2);
                            if (z > 1)
                            {
                                maxPer = Math.Max(maxPer, locPercents.Item3);
                            }
                            percent++;
                            while (maxPer > percent)
                            {
                                percent++;
                            }
                            if (percent > 100)
                            {
                                Console.WriteLine("Outer ring complete.");
                                alive = false;
                            }
                            else
                            {
                                Console.WriteLine("Moving \"add\" ring outward to {0}%", percent);
                                var newPosition = StaticMethods.AddCircle(new ValueTuple <ushort, ushort>(x, y), Math.Min(((double)percent / 100.0), 1.0));
                                if (z != 1)
                                {
                                    newPosition = StaticMethods.AddEllipsoid(new ValueTuple <ushort, ushort, ushort>(x, y, z), Math.Min(((double)percent / 100.0), 1.0));
                                }
                                int pick = (int)Math.Floor(StaticMethods.GetRandomNumber() * newPosition.Count);
                                var newLocationShape = new CALocationShape(CACreationLocationShapeType.Circle, new ValueTuple <ushort, ushort, ushort>(x, y, z), Math.Min(((double)percent / 100.0), 1.0));
                                (changeRule.Thens[1] as CAThenCreate).Location = newLocationShape;
                            }
                        }
                    }
                });
            }
            else
            {
                (changeRule.Thens[1] as CAThenCreate).Failure += ((object source, CreationEventArgs e) =>
                {
                    if (e.Cause == CreationEventArgs.CreationStatus.Failure_AgentExists)
                    {
                        alive = false;
                    }
                });
            }
            (changeRule.Thens[1] as CAThenCreate).Success += ((object source, CreationEventArgs e) =>
            {
                while (ca.Graph.AgentCells.Select(xyz => ca.Graph.GetCell(xyz).Agent.GetStateProperty()).Count() > 1)
                {
                    var location = ca.Graph.AgentCells[0];
                    var cell = ca.Graph.GetCell(location);
                    var stateProperty = cell.Agent.GetStateProperty();
                    if (StaticMethods.CheckEquality(stateProperty, CAEquality.Equal_to, state1.Item2))
                    {
                        ca.Graph.RemoveAgentCell(location);
                    }
                }
            });
            ca.AddRule(changeRule);
            ca.AddRule(moveRule);

            var position = StaticMethods.AddCircle(new ValueTuple <ushort, ushort>(x, y), Math.Min(((double)percent / 100.0), 1.0));

            if (z != 1)
            {
                position = StaticMethods.AddEllipsoid(new ValueTuple <ushort, ushort, ushort>(x, y, z), Math.Min(((double)percent / 100.0), 1.0));
            }

            ca.AddAgents(new List <ValueTuple <Dictionary <string, dynamic>, ValueTuple <ushort, ushort, ushort> > > {
                new ValueTuple <Dictionary <string, dynamic>, ValueTuple <ushort, ushort, ushort> >(edge, position[1])
            });

            Console.WriteLine("Press Enter to begin.");
            Console.ReadKey();
            //Console.WriteLine("When you see the task complete line below, press any key to continue.");
            DateTime now = DateTime.Now;

            Console.WriteLine("Dimensions: {0}, {1}, {2}", x, y, z);
            Task output = Task.Factory.StartNew(() =>
            {
                while (alive && !(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape))
                {
                    ca.Run();
                    Console.Write("\rIteration {0} {1}   ", ca.Iteration, ca.Graph.AgentCells.Last().ToString());
                }
                Console.WriteLine("");
            });

            output.Wait();
            Console.WriteLine("Task complete after: " + (DateTime.Now - now).TotalSeconds + " seconds");
            var    image    = StaticMethods.MakeImage(ca);
            string filename = path + System.IO.Path.DirectorySeparatorChar + start.ToString("o").Replace(':', '.') + " Iteration " + ca.Iteration + ".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();
        }
Exemple #6
0
        public CAGraph Copy(CA ca)
        {
            var graph = new CAGraph(ca, this.Dimensions, this.Shape, this.AgentCells, this.Cells, this.Properties);

            return(graph);
        }