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)); } }
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()); }
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(); }
// 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, }); }
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); }