Condividi tramite



Marzo 2016

Volume 31 Numero 3

Il presente articolo è stato tradotto automaticamente.

C# - simulazione di eventi distinti: esempio di incremento della popolazione

Da Arnaldo Perez Perez

Nel corso della cronologia, la possibilità di simulare è supportato lo sviluppo di scienze più. Modelli medici simulazione del corpo umano migliorano lo Studio di anatomia risorse umana. Giochi di simulazione di computer, ad esempio "World Warcraft" ricreare un intero mondo e "Simulatore di volo" consente di formare i piloti verso terra. Vari programmi di simulazione esplorare risposte attentati, diseases pandemic e altri problemi possibili. Anche dinosaurs simulato nell'hint "Jurassic Park" film l'ampia dell'applicazione di simulazione e il proprio potenziale.

Simulazione è una tecnica in cui un sistema reale o un processo viene emulato da un modello progettato. Il modello incapsula tutte le funzionalità del sistema e comportamenti; la simulazione è l'esecuzione di questo sistema nel tempo. Esistono varie fasi di progettazione di una simulazione:

  • Definizione del sistema da modellare, che è necessario studiare il problema, identificare le proprietà dell'ambiente e specificare gli obiettivi da raggiungere.
  • La formulazione del modello, che include la definizione di tutte le variabili e le relazioni logiche e creazione di diagrammi di flusso necessari.
  • Definizione dei dati del modello richiesto per produrre il risultato desiderato.
  • Generazione di un'implementazione computerizzata del modello.
  • Verifica se il modello implementato soddisfa la progettazione.
  • La convalida tramite confronto simulatore rappresenta in effetti sistema reale viene simulato.
  • Provare a generare dati desiderati utilizzando il simulatore.
  • L'analisi e interpretazione dei risultati dal simulatore e prendere decisioni in base a questi risultati.
  • Documentare il modello creato e il simulatore come uno strumento.

Simulazioni comprendono in genere un processo continuo o discreti eventi. Per simulare un sistema meteorologico, ad esempio, il rilevamento si verifica continuamente come tutti gli elementi sono costantemente. Di conseguenza, la variabile di temperatura posizionata sulla variabile ora sarebbe rappresentata da una curva continua. Al contrario, takeoffs aereo o sbarchi si verificano come punti nel tempo e, di conseguenza, una simulazione può prendere in considerazione solo gli eventi o i momenti precisi e ignorare tutte le altre. Questo tipo di simulazione è noto come simulazione di eventi discreti (DES), ed è ciò che mi occuperò di questo articolo.

Simulazione di eventi discreti

DES Modella un sistema o un processo come una sequenza ordinata di singoli eventi nel tempo, vale a dire dall'ora di un evento all'ora dell'evento successivo. Di conseguenza, in una simulazione di DES, ora è in genere molto più breve tempo reale.

Quando si sviluppa un DES, sono disponibili sei elementi principali da considerare:

Gli oggetti rappresentano gli elementi di sistema reale. Dispongono di proprietà, si riferiscono a eventi, consumano risorse e entrano ed escono code nel tempo. Il decollo aereo e uno scenario di destinazione indicato in precedenza, gli oggetti saranno aerei. In un sistema sanitario, oggetti potrebbero essere pazienti o organi. In un sistema di magazzino, gli oggetti sarebbe i prodotti in magazzino. Gli oggetti devono interagire tra loro o con il sistema e possono essere creati in qualsiasi momento durante una simulazione.

Le proprietà sono funzionalità specifiche per ogni oggetto (dimensione, di destinazione ora, sesso, prezzo e così via) che sono archiviate in modo da determinare le risposte a diversi scenari che potrebbero verificarsi nella simulazione; tali valori possono essere modificati.

Gli eventi sono operazioni che possono verificarsi nel sistema, in particolare agli oggetti, ad esempio la destinazione di viaggio, l'arrivo di un prodotto in un magazzino, l'aspetto di una determinata malattia e così via. Gli eventi possono verificarsi e si ripresenti in qualsiasi ordine.

Le risorse sono elementi che forniscono servizi agli oggetti (ad esempio, un elenco di destinazione in un aeroporto, le celle di archiviazione di un warehouse e i medici in corso). Quando una risorsa è occupata e richiede un oggetto, l'oggetto deve accodare e attendere che la risorsa è disponibile.

Le code sono i percorsi in cui gli oggetti sono organizzati per attendere il rilascio di una risorsa attualmente occupata. Le code possono avere una capacità massima e possono avere diversi approcci chiamanti: first-in-first-out (FIFO), last-in-first-out (LIFO) o basato su alcuni criteri o priorità (progressione malattia, il consumo di carburante e così via).

Tempo (come accade in uno scenario reale) è essenziale nella simulazione. Per misurare il tempo, un orologio viene avviato all'inizio di una simulazione e quindi può essere utilizzato per tenere traccia particolari periodi di tempo (ora di partenza e arrivo, il tempo di trasporto, tempo trascorso con alcuni sintomi e così via). Tale verifica è fondamentale poiché consente di sapere quando deve verificarsi l'evento successivo.

Poiché la programmazione di simulazione può essere complicata, sono stati apportati molti tentativi di creare linguaggi che contengono tutti i requisiti del paradigma di simulazione per facilitare lo sviluppo. Uno di questi linguaggi è SIMULA, inventato nel 1960 Ole Johan e Kristen Nygaard e prima di introdurre il concetto di programmazione a oggetti (OOP) paradigma di programmazione principali di oggi. Al giorno d'oggi, lo stato attivo è sulla creazione di pacchetti, Framework o librerie che incorporano i programmatori necessaria durante la creazione di una simulazione. Queste librerie sono pensate per essere chiamati da normali linguaggi come c#, C++, Java o Python.

In "Una cronologia di discreti evento simulazione linguaggi di programmazione," up proposta sei requisiti minimi deve soddisfare qualsiasi linguaggio di programmazione di DES (bit.ly/1ZnvkVn):

  • Generazione di numeri casuali.
  • Trasformatori processi, per consentire le variabili diverso da variabili casuale uniforme.
  • Elaborazione dell'elenco, per facilitare la creazione, modifica ed eliminazione di oggetti.
  • Analisi statistiche, per fornire un riepilogo del comportamento del modello descrittivo.
  • Report di generazione, per assistere nella presentazione di grandi set di dati e facilitare il processo decisionale.
  • Un meccanismo di flusso del tempo.

Questi requisiti possono tutti essere soddisfatte in c#, pertanto in questo articolo illustrerò una simulazione di eventi discreti per la crescita del popolamento sviluppata in c#.

DES per la crescita del popolamento

Crescita della popolazione è uno dei molti aspetti considerati nello studio di come popolamenti (animali e piante) cambiano nel tempo e spazio e interagiscono con i relativi ambienti. Popolamenti sono gruppi di organismi della stessa specie che risiedono nello stesso momento, a volte nello stesso spazio o ulteriormente delimitate da caratteristiche specifiche.

Perché è importante studiare demografico? Una migliore comprensione di come popolamenti aumentare o ridurre gli scienziati offre la possibilità di esecuzione di stime migliorate sulle modifiche di conservazione della biodiversità, utilizzo della risorsa, il cambiamento climatico, inquinamento, sanitario, esigenze di trasporto e così via. Fornisce inoltre approfondite come organismi interagiscono tra loro e con l'ambiente, un aspetto critico quando si valuta se un popolamento potrebbe raggiungere la prosperità o rifiutare.

In questo articolo presenterò un DES per la crescita della popolazione. L'obiettivo consiste nell'osservare come la popolazione si evolve nel tempo, alcune statistiche analizzando i risultati finali (dimensione della popolazione, persone, giovani e così via). Verrà avviato il popolamento con m maschio e n femmina individui, ognuno dei quali dispone di un'età associata. Chiaramente, m e n deve essere maggiore di zero o la simulazione sarebbe inutile. Gli oggetti in questo modello sono persone.

È in grado di avviare una relazione con un altro utente dopo un'età che distribuisce da una funzione di probabilità di Poisson con parametro λ = 18 anni. (Non è necessario conoscere a fondo Poisson, normale o esponenziale distribuzioni subito, verrà descritto nella sezione successiva).

Esiste un minore probabilità del 50% dei singoli utenti singoli e in grado di supportare opposto sesso coinvolgere tra loro e anche che si verifica solo quando la differenza di età non siano superiore a 5 anni. Figura 1 viene illustrato un esempio della probabilità di una relazione tra due utenti finali.

Figura 1 probabilità di una relazione finale

Età media Probabilità
14-20 0.7
21-28 0.5
29+ 0.2

Persone coinvolte in una relazione possono contenere un elemento figlio dopo un periodo di tempo che distribuisce il mezzo di una funzione esponenziale con parametro λ = 8 anni.

Una donna possa ottenere incinta se ne ha un'età che segue una funzione di distribuzione normale (a campana) con parametri µ = 28 e σ2= 8 anni. Ogni donna ha un numero di elementi figlio che vengono distribuiti da una normale funzione con parametri µ = σ 2and2= 6 anni. (Il parametro µ rappresenta l'età media durante σ2è la misura della variabilità age).

Ogni individuo ha una permanenza presunta delle pagine che vengono distribuiti da una funzione di probabilità di Poisson con parametro λ = 70 anni, in cui λ rappresenta la media di permanenza presunta.

Nella descrizione precedente è possibile identificare i diversi eventi:

  • Avvio di una relazione.
  • Una relazione di fine.
  • Recupero incinta.
  • Con un elemento figlio.
  • Morire.

Ogni evento è accompagnato da una variabile casuale discreta che determina il momento in cui si verificherà l'evento.

Distribuzioni probabilistiche

Una variabile casuale discreta è uno cui set di valori è finito o infinito countably. Ovvero, i valori possono essere elencati come una sequenza finita o infinita di valori 1, 2, 3... Per una variabile casuale discreta, la distribuzione di probabilità è un grafico, tabella o formula che assegna un valore di probabilità per ogni valore possibile. La somma di tutte le probabilità deve essere 1, e ogni singola probabilità deve essere compreso tra 0 e 1. Ad esempio, quando si genera una matrice equo (tutti i lati ugualmente probabile), alla variabile casuale discreta X che rappresenta i possibili risultati avrà la distribuzione probabilistica X(1) = 1/6, X(2) = 1/6,..., X(6) = 1/6. Tutti i lati sono ugualmente probabili, pertanto la probabilità di ogni assegnata è 1/6.

µ E l parametri indicano la media (valore previsto) nella loro distribuzione corrispondente. Il valore medio rappresenta il valore impiegato in Media variabile casuale. In altre parole, è la somma E = [(each possible outcome) × (probabilità di tale risultato)], dove E indica la Media. Nel caso di matrice, la media sarebbe E = 2 + 1/6/6 + 3/6 + 4/6 + 5/6 + 6/6 = 3,5. Si noti che il risultato 3.5 è effettivamente a metà tra tutti i valori possibili che dado può richiedere; è il valore previsto quando la matrice viene eseguito il rollback di un numero elevato di volte.

Parametro σ2 indica la varianza della distribuzione. Varianza rappresenta la dispersione dei valori possibili della variabile casuale ed è sempre un valore non negativo. Piccole variazioni (prossimo a 0) tendono a indicare che i valori si avvicinano tra loro e con la Media; elevata varianze (prossimi a 1) indicano grande distanza tra i valori e dal valore medio.

Probabilità di POISSON è una distribuzione discreta che esprime le probabilità relative al numero di eventi per ogni unità di tempo (vedere Figura 2). In genere applicato quando la probabilità di un evento è piccola e il numero di opportunità per la generazione di grandi dimensioni. Il numero di stampe errate in un libro, i clienti che arrivano a un centro business, automobili che transitano semafori e morte all'anno in un determinato gruppo di età è tutti esempi di applicazioni di distribuzione di Poisson.

Distribuzione di Poisson, parametro λ = 18
La distribuzione di Poisson figura 2, parametro λ = 18

Una distribuzione esponenziale esprime il tempo tra gli eventi in un processo di Poisson (vedere Figura 3). Ad esempio, se si vuole eseguire un processo di Poisson che descrive il numero di clienti che arrivano a un centro business durante un certo periodo di tempo, potrebbe essere interessati a una variabile casuale che indicano la quantità di tempo passato prima che il primo cliente arrivato. Una distribuzione esponenziale può essere utilizzato a questo scopo. Potrebbe anche essere applicato ai processi fisica, ad esempio rappresentare la durata di particelle, dove λ sarebbe indica la frequenza con cui verrà applicata la particella.

Distribuzione esponenziale, parametro λ = 8
Distribuzione esponenziale figura 3, parametro λ = 8

La distribuzione normale descrive le probabilità che tendono a essere un valore centrale, senza distorsione a sinistra o destra, come illustrato nella Figura 4. Distribuzioni normali sono simmetriche e possedere curve campana densità con un unico picco una Media. Il 50% della distribuzione si trova a sinistra la media e il 50% a destra. La deviazione standard indica la diffusione o girth della curva a campana; minore sarà la deviazione standard più concentrato i dati. Sia la media e la deviazione standard devono essere contrassegnati come parametri alla distribuzione normale. Molti fenomeni naturali attenersi a una distribuzione normale: pressione sangue, altezza degli utenti, gli errori nelle misurazioni e molte altre.

NormalDistribution, parametri µ = 28 e σ2 = 8 anni
NormalDistribution figura 4, i parametri µ = 28 e σ2 = 8 anni

Ora verrà illustrato come implementare la crittografia DES proposta in un linguaggio più diffuso, elegante e sofisticato, ad esempio c#.

 

Implementazione

Per sviluppare questa simulazione è necessario sfruttare tutti i vantaggi del paradigma OOP. L'idea è di ottenere il codice più leggibile possibile. Applicazioni scientifiche tendono a essere complessa e difficile da comprendere ed è essenziale per renderle più chiare possibili, in modo che altri utenti possono comprendere il codice. Verrà sviluppata l'applicazione come applicazione console in c#, con la struttura illustrata nella Figura 5.

La struttura dell'applicazione di simulazione
Figura 5, la struttura dell'applicazione di simulazione

Un percorso logico è essenziale; Si noti il modo in cui la struttura dello spazio dei nomi gestisce il proprio buon senso: Simulation.DES.PopulationGrowth.

La cartella eventi contiene un file Event.cs, che definisce un tipo di enumerazione che rappresenta tutti i possibili eventi nella simulazione:

namespace DES.PopulationGrowth.Events
{
public enum Event
  {
Capable Engaging,
Birth EngageDisengage,
GetPregnant,
ChildrenCount,
TimeChildren,
    Die
  }
}

La cartella di oggetti contiene tutte le classi correlate a singoli utenti; Queste sono le parti di codice che beneficeranno più OOP. Esistono tre classi correlate a singoli utenti: Singolo, maschio e femmina. Il primo è una classe astratta e gli altri ereditano da esso. vale a dire i maschi e femmine sono persone. La maggior parte di codice si verifica nella classe singoli. Figura 6 Mostra le proprietà e metodi.

Proprietà e metodi della classe singola
Figura 6 proprietà e metodi della classe singola

Di seguito è riportata una descrizione di ogni proprietà:

  • Età: Singoli età.
  • Due: Null se singoli è singola, in caso contrario propria coppia, un altro utente.
  • Dovrà: True se l'utente è coinvolta in una relazione, false in caso contrario.
  • Durata: Durata in cui i singoli muore.
  • RelationAge: Durata in cui i singoli possono avviare una relazione.
  • TimeChildren: Ora nella simulazione (non age) in cui l'utente può avere elementi figlio.

Di seguito è una descrizione dei relativi metodi:

  • Disattivare: Termina la relazione tra due persone.
  • EndRelation: Determina se deve terminare la relazione, in base alla tabella probabilità in Figura 1.
  • FindPartner: Trova un partner disponibile per un singolo.
  • SuitablePartner: Determina se un utente è adatto per l'avvio di una relazione (sesso età differenza e opposto).
  • SuitableRelation: Determina se distinti possono avviare una relazione. è unico e un'età per l'avvio di una relazione.
  • ToString: Eseguire l'override per rappresentare singole informazioni sotto forma di stringa.

La classe inizia con la definizione di tutte le proprietà e successivamente il costruttore che imposti semplicemente l'età:

public abstract class Individual
  {
public int Age { get; set; }
public int RelationAge{ get; set; }
public int LifeTime{ get; set; }
public double TimeChildren{ get; set; }
public Individual Couple { get; set; }
protected Individual(int age)
{
  Age = age;
}

I metodi SuitableRelation e SuitablePartner e la proprietà Engaged sono test appena logici, piuttosto semplice:

public bool SuitableRelation()
{
return Age >= RelationAge&& Couple == null;
}
public bool SuitablePartner(Individual individual)
{
return ((individual is Male && this is Female) ||
(individual is Female && this is Male)) &&Math.Abs(individual.Age - Age) <= 5;
}  
public bool Engaged
{
get { return Couple != null; }
}

Il metodo di disattivazione interrompe la relazione impostando il campo di due su null per la coppia e successivamente i singoli. Imposta inoltre il tempo di disporre di figli su 0 perché non è più sta impegnati.

public void Disengage()
{
Couple.Couple = null;
Couple = null;
TimeChildren = 0;
}

Il metodo EndRelation è fondamentalmente una traduzione della tabella di probabilità per determinare la probabilità di una termine di relazione. Utilizza una variabile casuale uniforme, che produce un valore casuale nell'intervallo [0, 1] equivale a ottenere una percentuale di accettazione. Le distribuzioni di dizionario, viene creato nella classe di simulazione (descritta brevemente) e contiene coppie (eventi, distribuzione di probabilità), quindi associare tutti gli eventi con la distribuzione:

public bool EndRelation(Dictionary<Event, IDistribution> distributions)
{
var sample =
  ((ContinuousUniform) distributions[Event.BirthEngageDisengage]).Sample();
if (Age >= 14 && Age <= 20 && sample <= 0.7)
return true;
if (Age >= 21 && Age <= 28 && sample <= 0.5)
return true;
if (Age >= 29 && sample <= 0.2)
return true;
return false;
}

Il metodo FindPartner, illustrato nella Figura 7, trova un partner disponibile per l'istanza utente. Riceve come input l'elenco di popolamento, l'ora corrente di simulazione e il dizionario di distribuzioni.

Figura 7 il metodo FindPartner

public void FindPartner(IEnumerable<Individual> population, int currentTime,
  Dictionary<Event, IDistribution> distributions)
{
foreach (var candidate in population)
if (SuitablePartner(candidate) &&
candidate.SuitableRelation() &&
((ContinuousUniform) distributions[Event.BirthEngageDisengage]).Sample() <= 0.5)
{
// Relate them
candidate.Couple = this;
Couple = candidate;
// Set time for having child
var childTime = ((Exponential)  distributions[Event.TimeChildren]).Sample()*100;
// They can have children on the simulated year: 'currentTime + childTime'.
candidate.TimeChildren = currentTime + childTime;
TimeChildren = currentTime + childTime;
break;
}
}

Infine, il metodo ToString definisce la rappresentazione di stringa di un singolo:

public override string ToString()
{
Return string.Format("Age: {0} Lifetime {1}", Age, LifeTime);
}

La classe maschio è molto semplice:

public class Male: Individual
{
public Male(int age) : base(age)
{
}
public override string ToString()
{
return base.ToString() + " Male";
}
}

La classe femmina è un po' più complicata perché include un trattamento gravidanza, nascita e così via. La definizione della classe inizia con la dichiarazione di tutte le proprietà e il costruttore:

public class Female :Individual
{
public bool IsPregnant{ get; set; }
public double PregnancyAge{ get; set; }
public double ChildrenCount{ get; set; }
public Female(int age) : base(age)
{
}
}

Di seguito sono le proprietà della classe femmina:

  • IsPregnant: Determina se questo donna incinta.
  • PregnancyAge: Determina l'età in cui è possibile ottenere una donna incinta.
  • ChildrenCount: Indica numero di elementi figlio per dare vita a.

Di seguito sono i metodi che contiene:

  • SuitablePregnancy: Determina se questo donna possa ottenere incinta.
  • GiveBirth: Indica una donna offrendo di nascita, aggiunta nuovo utente per il popolamento.
  • ToString:override: Utilizzata per rappresentare informazioni femmine sotto forma di stringa.

SuitablePregnancy è un metodo di test che restituisce true quando la donna istanza soddisfa ogni condizione per il recupero incinta:

public bool SuitablePregnancy(intcurrentTime)
  {
return Age >= PregnancyAge && currentTime <= TimeChildren && ChildrenCount > 0;
}

Il metodo GiveBirth, illustrato nella Figura 8, il codice che aggiunge e inizializza i nuovi utenti nella popolazione.

Figura 8 TheGiveBirth metodo

public Individual GiveBirth(Dictionary<Event, IDistribution> distributions, int currentTime)
  {
var sample =
  ((ContinuousUniform) distributions[Event.BirthEngageDisengage]).Sample();
var child = sample > 0.5 ? (Individual) newMale(0) : newFemale(0);
// One less child to give birth to
ChildrenCount--;
child.LifeTime = ((Poisson)distributions[Event.Die]).Sample();
child.RelationAge = ((Poisson)distributions[Event.CapableEngaging]).Sample();
if (child is Female)
{
(child as Female).PregnancyAge =
  ((Normal)distributions[Event.GetPregnant]).Sample();
(child as Female).ChildrenCount =
  ((Normal)distributions[Event.ChildrenCount]).Sample();
}
if (Engaged && ChildrenCount> 0)
{
TimeChildren =
  currentTime + ((Exponential)distributions[Event.TimeChildren]).Sample();
Couple.TimeChildren = TimeChildren;
}
else
TimeChildren = 0;
IsPregnant = false;
return child;
  }

Viene generato un campione uniforme per determinare se il nuovo utente sarà femmina o male, ognuno con una probabilità del 50% (0.5). Il valore ChildrenCount viene decrementato di 1, che indica che questo donna ha un minore figlio per dare vita a. Il resto del codice si riferisce a singoli inizializzazione e reimpostare alcune variabili.

Il metodo ToString cambia il modo in cui le femmine vengono rappresentate come stringhe:

public override string ToString()
  {
return base.ToString() + " Female";
}

Poiché tutte le funzioni relative ai singoli utenti sono state inserite in classi separate, la classe di simulazione è ora molto più semplice. Le proprietà e il costruttore sono all'inizio del codice:

public class Simulation
  {
public List<Individual> Population { get; set; }
public int Time { get; set; }
private int _currentTime;
private readonly Dictionary<Event, IDistribution> _distributions ;

Le proprietà e variabili sono autodescrittivi e alcuni sono stati descritti in precedenza. Ora rappresenta il tempo (in anni) a lungo termine la simulazione e _currentTime rappresenta l'anno corrente della simulazione. Il costruttore in questo caso, illustrato nella Figura 9, è più complicato perché include l'inizializzazione di variabili casuali per ogni individuo.

Figura 9 il costruttore di classe di simulazione

public Simulation(IEnumerable<Individual> population, int time)
{
Population = new List<Individual>(population);
Time = time;
_distributions = new Dictionary<Event, IDistribution>
{
{ Event.CapableEngaging, new Poisson(18) },
{ Event.BirthEngageDisengage, new ContinuousUniform() },
{ Event.GetPregnant, new Normal(28, 8) },
{ Event.ChildrenCount, new Normal(2, 6) },
{ Event.TimeChildren, new Exponential(8) },
{ Event.Die, new Poisson(70) },
                                 };
foreach (var individual in Population)
{
// LifeTime
individual.LifeTime = ((Poisson) _distributions[Event.Die]).Sample();
// Ready to start having relations
individual.RelationAge = ((Poisson)_distributions[Event.CapableEngaging]).Sample();
// Pregnancy Age (only women)
if (individual is Female)
                {
(individual as Female).PregnancyAge = ((Normal) _distributions[Event.GetPregnant]).Sample();
(individual as Female).ChildrenCount = ((Normal)_distributions[Event.ChildrenCount]).Sample();
}
}
}

Infine, il metodo Execute nella Figura 10, avviene tutta la logica di simulazione.

Figura 10 di Execute (metodo)

public void Execute()
{
while (_currentTime< Time)
{
// Check what happens to every individual this year
for (vari = 0; i<Population.Count; i++)
{
var individual = Population[i];
// Event -> Birth
if (individual is Female&& (individual as Female).IsPregnant)
Population.Add((individual as Female).GiveBirth(_distributions,
  _currentTime));
// Event -> Check whether someone starts a relationship this year
if (individual.SuitableRelation())
individual.FindPartner(Population, _currentTime, _distributions);
// Events where having an engaged individual represents a prerequisite
if (individual.Engaged)
{
// Event -> Check whether arelationship ends this year
if (individual.EndRelation(_distributions))
individual.Disengage();
// Event -> Check whether a couple can have a child now
if (individual is Female &&
(individual as Female).SuitablePregnancy(_currentTime))
(individual as Female).IsPregnant = true;
}
// Event -> Check whether someone dies this year
if (individual.Age.Equals(individual.LifeTime))
{
// Case: Individual in relationship (break relation)
if (individual.Engaged)
individual.Disengage();
Population.RemoveAt(i);
}
individual.Age++;
_currentTime++;
}
}

Le iterazioni nel ciclo esterno rappresentano anni che vanno nella simulazione. Il ciclo più interno passa attraverso gli eventi che potrebbero verificarsi agli utenti in tale anno specifico.

Per vedere come il popolamento si evolve nel tempo, è stata impostata una nuova applicazione console, illustrata nella Figura 11.

Figura 11 la popolazione nel corso del tempo di visualizzazione

static void main()
{
var population = new List<Individual>
{
new Male(2),
new Female(2),
new Male(3),
new Female(4),
new Male(5),
new Female(3)
};
var sim = new Simulation(population, 1000);
sim.Execute();
// Print population after simulation
foreach (var individual in sim.Population)
Console.WriteLine("Individual {0}", individual);
Console.ReadLine();
}

Figura 12 Mostra la popolazione dopo anni di 1.000.

Popolamento dopo anni 1.000
Figura 12 popolamento dopo anni 1.000

In questo articolo ho sviluppato una simulazione di eventi discreti per vedere come una popolazione si evolve nel tempo. L'approccio orientato a oggetti si è rivelato molto utile per ottenere codice leggibile e conciso che i lettori possono provare e migliorano se necessario.


Arnaldo Pérez Castañoè una base Cuba di informatica. È l'autore di una serie di testi di programmazione, "JavaScript Fácil", "Y HTML, CSS Fácil" e "Fácil Python" (Marcombo s). Il suo esperienza include Visual Basic, c#, .NET Framework e intelligenza artificiale e offre servizi come freelance tramite nubelo.com. Musica e cinema sono alcuni dei suoi passioni. Contattarlo all'indirizzo <arnaldo.skywalker@gmail.com.>

Grazie al seguente esperto tecnico Microsoft che ha esaminato in questo articolo: James McCaffrey