예제 #1
0
        public static byte[] GetBitmapBinary(InfectionModel model)
        {
            using (var bitmap = new Bitmap(model.InitialSettings.Size.Width, model.InitialSettings.Size.Height))
            {
                for (var i = 0; i < bitmap.Width; i++)
                {
                    for (var j = 0; j < bitmap.Height; j++)
                    {
                        bitmap.SetPixel(i, j, StatusColors[model.Statuses[i, j]]);
                    }
                }

                return(ImageToBytes(bitmap, ImageFormat.Png));
            }
        }
예제 #2
0
        public AppModel()
        {
            _CurrentInfection       = InitializeInfection(InitialSettings.ToValue());
            InfectionSnapshot.Value = _CurrentInfection;

            CreateObserver(InitialSettings)
            .Throttle(TimeSpan.FromSeconds(0.1))
            .Subscribe(_ =>
            {
                _CurrentInfection       = InitializeInfection(InitialSettings.ToValue());
                InfectionSnapshot.Value = _CurrentInfection;
            });

            IsRunning
            .Where(b => b)
            .ObserveOn(TaskPoolScheduler.Default)
            .Subscribe(_ => Simulate());
        }
예제 #3
0
        void Simulate()
        {
            var subscription = Observable.Interval(SnapshotInterval)
                               .Subscribe(_ => InfectionSnapshot.Value = _CurrentInfection);

            if (_CurrentInfection.Turn > 0)
            {
                _CurrentInfection = InitializeInfection(InitialSettings.ToValue());
            }

            while (IsRunning.Value)
            {
                var rs = RealtimeSettings.ToValue();
                Thread.Sleep(TimeSpan.FromSeconds(rs.ExecutionInterval));
                _CurrentInfection = NextInfection(_CurrentInfection, rs);
            }

            subscription.Dispose();
        }
예제 #4
0
        // S' = θR - βSI
        // I' = βSI - γI
        // R' = γI - θR
        static InfectionModel NextInfection(InfectionModel model, VRealtimeSettings rs)
        {
            var β = rs.InfectionRate;
            var γ = rs.RecoveryRate;
            var θ = rs.DeimmunizationRate;

            var size     = model.InitialSettings.Size;
            var statuses = new InfectionStatus[size.Width, size.Height];

            for (var i = 0; i < size.Width; i++)
            {
                for (var j = 0; j < size.Height; j++)
                {
                    switch (model.Statuses[i, j])
                    {
                    case InfectionStatus.Susceptible:
                        var count_I = DataModelHelper.GetNeighborPoints(size, new Point(i, j), rs.IsMapLooping)
                                      .Select(p => model.Statuses[p.X, p.Y])
                                      .Count(x => x == InfectionStatus.Infectious);
                        statuses[i, j] = count_I == 0 ? InfectionStatus.Susceptible : RandomHelper.GetRandomElement(1 - Math.Pow(1 - β, count_I), InfectionStatus.Infectious, InfectionStatus.Susceptible);
                        break;

                    case InfectionStatus.Infectious:
                        statuses[i, j] = RandomHelper.GetRandomElement(γ, InfectionStatus.Recovered, InfectionStatus.Infectious);
                        break;

                    case InfectionStatus.Recovered:
                        statuses[i, j] = RandomHelper.GetRandomElement(θ, InfectionStatus.Susceptible, InfectionStatus.Recovered);
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }
            }

            return(new InfectionModel
            {
                InitialSettings = model.InitialSettings,
                Turn = model.Turn + 1,
                Statuses = statuses,
            });
        }
예제 #5
0
        public static PopulationSummary ToSummary(InfectionModel model)
        {
            var width  = model.InitialSettings.Size.Width;
            var height = model.InitialSettings.Size.Height;

            var summary = new PopulationSummary
            {
                Total = width * height,
            };

            for (var i = 0; i < width; i++)
            {
                for (var j = 0; j < height; j++)
                {
                    switch (model.Statuses[i, j])
                    {
                    case InfectionStatus.Susceptible:
                        summary.Susceptible++;
                        break;

                    case InfectionStatus.Infectious:
                        summary.Infectious++;
                        break;

                    case InfectionStatus.Recovered:
                        summary.Recovered++;
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }
            }

            return(summary);
        }