Concetti Chiave

  • La simulazione dell'evoluzione biologica utilizza una matrice per rappresentare gli organismi, dove ciascuno occupa una cella e le loro interazioni sono regolate da regole specifiche.
  • Un organismo sopravvive se ha 2 o 3 vicini, mentre muore per solitudine (0 o 1 vicino) o sovrappopolamento (4-8 vicini).
  • La configurazione iniziale degli organismi può essere inserita manualmente o generata casualmente e viene visualizzata tramite asterischi e spazi.
  • Due matrici vengono utilizzate per memorizzare la generazione attuale e quella futura, scambiandosi di ruolo ad ogni iterazione per gestire l'evoluzione.
  • Il programma esegue un ciclo infinito di evoluzioni, calcolando i vicini e aggiornando le generazioni in base alle regole di sopravvivenza e nascita.

Simulazione dell'evoluzione biologica

Un meccanismo biologico di evoluzione viene simulato supponendo che gli organismi che si considerano

occupino ciascuno una cella di una matrice di dimensioni pari a MAX righe e MAX colonne. Il meccanismo di

evoluzione è basato sulle seguenti regole che determinano il passaggio da una generazione alla successiva:

· un organismo sopravvive se nelle celle vicine ha 2 o 3 organismi viventi

· un organismo cessa di esistere se nelle celle vicine ha:

- 0 o 1 organismi viventi (solitudine) oppure

- da 4 a 8 organismi viventi (sovrappopolamento)

· un nuovo organismo nasce in una cella se nelle celle vicine coi sono 3 organismi viventi

Implementazione del programma in C

Realizzare un pgm C in grado, a partire da una configurazione iniziale, di mostrare l'evoluzione della specie.

SPECIFICHE

1) Configurazione iniziale:

· Leggere da tastiera le coordinate dei soli elementi vivi. L'input -1,-1 indica la terminazione di tale fase.

· (in alternativa) Generazione casuale degli elementi vivi.
2) Visualizzazione configurazione iniziale e generazioni successive:

Tabella di caratteri dove:

· Un asterisco indica la presenza di un organismo vivente

· Uno spazio indica assenza di vita

Esempio di evoluzione della specie

ESEMPIO

L'evoluzione di una specie risulta alquanto interessante dal punto di vista grafico. Sia l'input il seguente

(indicante la posizione dei soli elementi vivi)

2 1

2 2

2 3

-1 -1

L'evoluzione della popolazione di organismi risulta la seguente (in cui si è evidenziato il contorno della

matrice):

Configurazione Prima E così via …..

Iniziale generazione:

####### #######

# # # #

# # # * #

# *** # # * #

# # # * #

# # # #

####### #######

IPOTESI DI SOLUZIONE:

Ipotesi di soluzione con matrici

La soluzione prevede che in ciascun istante vengano memorizzate due generazioni della specie: la generazione

attuale e quella futura. Con il passaggio da una generazione a quella successiva la generazione futura diviene

quella attuale e una nuova generazione viene valutata. Questo meccanismo può essere realizzato mediante l'uso

di due matrici che contengono due generazioni successive e che si "scambino di ruolo" ad ogni iterazione. Una

soluzione particolarmente elegante può essere realizzata attraverso l'utilizzo di una matrice a tre dimensioni:

#define STATO 2

#define MAX 5

int vita [STATO][MAX][MAX]; //var globale

Una variabile (stato nel programma ) indica che la generazione attuale si trova nella matrice anteriore e quella

futura nella matrice posteriore ( se stato è uguale a 0) e la situazione inversa (se stato vale 1).

La matrice contiene 1 se l'organismo corrispondente è vivo, 0 altrimenti.

Determinazione dei vicini

Un ulteriore problema è la determinazione del numero di organismi vicini ad un organismo dato. Tale valore

può essere individuato, a partire dall'organismo nell'elemento (i,j), indicando gli offset, cioè gli scostamenti, sui

due indici.

i-1,j-1 i-1,j i-1,j+1

i,j-1 i,j i,j+1

i+1,j-1 i+1,j i+1,j+1

Tali offset (-1,0,+1) possono essere memorizzati in una coppia di vettori.

#define DIREZIONI 8

int scostX [DIREZIONI] = { 0, 1, 1, 1, 0, -1, -1, -1}; //var globale

int scostY [DIREZIONI] = { 1, 1 , 0, -1, -1, -1, 0, 1}; //var globale

int stato; //var booleana 0: stato attuale 1: stato futuro (locale alla funzione main())

Nel nostro caso quindi la var stato viene inizializzata a 0 (configurazione iniziale).

Sottoprogrammi del codice

Individuazione dei sottopgm:

void insert(); //inserimento della configurazione iniziale

void visualizza(int stato); //visualizza una generazione (compresa la configurazione iniziale)

void aggiorna (int stato); // calcolo di una nuova generazione (sulla base degli elementi vicini

// e se la casella è viva o morta)

int vicini(int x,int y,int stato); // calcola il numero di vicini vivi all'elemento x,y

int viva(int x,int,y,int stato); //determina se una casella è viva: 1 viva, 0 morta

void azzera(int stato); // azzera la matrice relativa alla generazione futura

// preparandola a contenere nuovi dati

6

Il pgm quando termina?

Mai, ciclo infinito (di evoluzioni)

while(1)

{

…..

}

Domande da interrogazione

  1. Quali sono le regole fondamentali che governano la sopravvivenza e la nascita degli organismi nella simulazione?
  2. Un organismo sopravvive se ha 2 o 3 organismi viventi nelle celle vicine, mentre cessa di esistere se ha 0 o 1 organismi (solitudine) o da 4 a 8 organismi (sovrappopolamento). Un nuovo organismo nasce se ci sono 3 organismi viventi nelle celle vicine.

  3. Come viene gestita la configurazione iniziale degli organismi nella simulazione?
  4. La configurazione iniziale può essere letta da tastiera tramite le coordinate degli organismi viventi, terminando con l'input -1,-1, oppure può essere generata casualmente.

  5. Qual è la struttura della matrice utilizzata per memorizzare le generazioni degli organismi?
  6. La soluzione prevede l'uso di una matrice a tre dimensioni, dove una variabile di stato indica quale matrice contiene la generazione attuale e quale quella futura, con valori 1 per gli organismi vivi e 0 per quelli morti.

  7. Come vengono determinati i vicini di un organismo nella matrice?
  8. Il numero di organismi vicini è calcolato utilizzando offset predefiniti per le coordinate, che permettono di esaminare le celle adiacenti in tutte le direzioni.

  9. Qual è il comportamento del programma una volta avviato?
  10. Il programma entra in un ciclo infinito di evoluzioni, continuando a calcolare e visualizzare le generazioni degli organismi senza una condizione di terminazione.

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community