Professional Documents
Culture Documents
Lezione F.02 Implementazione di un modello multi-agente: basi di programmazione e del linguaggio C++ Antonello Lobianco
Titolo sezione
slide 1 of
Antonello Lobianco
Programma
Programma
Programma formalizzazione matematica di un'idea-modello
int main (){ float xa1, xa2, yb, va, vb, ta1, ta2, tb; cin >> xa1; cin >> xa2; cin >> yb; cin >> va; cin >> vb; ta1 = xa1/va; ta2 = xa2/va; tb = yb/vb; if (tb >= ta2 && tb <= ta1){ cout << Crash happening... << endl; } else { cout << Crash avoided.. << endl; } }
slide 3 of
Antonello Lobianco
implementazione completa del paradigma della programmazione ad oggetti ( a sua volta molto vicina concettualmente alla modellazione ad agenti) velocit di esecuzione utilizzabile in praticamente ogni contesto sviluppo non proprio velocissimo
neg
Compilazione ed esecuzione
compilazione trasformazione del codice sorgente in un programma eseguibile direttamente dalla macchina (codice oggetto o pi specificatamente codice eseguibile) linking collegamento dei vari codici oggetto in un unico eseguibile esecuzione implementazione da parte della macchina delle istruzioni contenute nel programma. Pu avvenire serialmente o parallelamente (multi-thread). Per alcuni linguaggi compilazione ed esecuzione avvengono in un unico passaggio (es. PHP, python..) Il compilatore intercetta tutti gli errori di sintassi e alcuni di logica (inizializzazione delle variabili..) restituendo dei warning o degli errori Compilazione: g++ agent.h agent.cpp main.cpp -c Linking: g++ agent.o main.o -o eseguibile Esecuzione: ./eseguibile
slide 6 of Antonello Lobianco
Il primo programma
/* Il primo programma in C++ Questo un commento multilinea */ #include <iostream> using namespace std; int main() { // funzione principale cout << Ciao mondo!!! << endl; return 0; }
Commenti: multilinea /* */ o single-line // Direttiva #include Namespace: regione di dichiarazione Funzione main: funzione principale di un programma Cout: console output Return: termina il programma Identazione e spazi
slide 7 of
Antonello Lobianco
Variabili
Come per funzioni ed oggetti, le variabili nel C++ vanno prima dichiarate e poi definite. Il C++ di per s gestisce solo tipi di dato elementari:
Per tutti gli altri tipi di dato (vettori e stringhe in primis) occorre utilizzare una libreria esterna. La libreria STL (Standard Template Library) viene fornita di default con tutti i compilatori ed generalmente sufficiente. E' possibile inoltre costruire tipi di dato personalizzati usando le strutture o le classi (che vedremo in seguito) Per passare da un tipo di dato ad un altro (quando possibile) occorre fare un casting manuale
slide 8 of Antonello Lobianco
Variabili
#include <iostream> #include <vector> using namespace std; main() { int nrows; int ncols; int nagents; cout << " Benvenuto nel programma di simulazione del modello di segregazione di Shelling " << endl; cout << "Inserire il numero di righe del modello..." << endl; cin >> nrows; cout << "Inserire il numero di colonne del modello..." << endl; cin >> ncols; cout << "Inserire il numero di agenti nel modello..." << endl; cin >> nagents; cout << "Modello programmato per gestire " << nrows << " righe e " << ncols << " colonne" << endl; float density; density = ( (float) nagents ) / ( ((float) nrows * ncols) ); cout << "Densit di " << density << " agenti/cella" << endl; return (0); }
slide 9 of
Antonello Lobianco
Funzioni
Una funzione una subroutine che contiene una o pi istruzione e quindi esegue un compito logico del programma. Spesso la divisione di un compito in una o pi funzioni a scelta del programmatore. Le funzioni possono restituire un valore e possono accettare uno o pi argomenti. A meno che gli argomenti non vengano passati per reference (vedremo..) tutto quello che si fa loro resta confinato nella funzione chiamata. Le funzioni (ma anche i blocchi di codice for, if, while..) definiscono infatti la loro regione di visibilit delle variabili (scope). In altre parole queste sono locali rispetto all'ambiente dove vengono definite. Solo le variabili definite fuori da qualunque funzione (main inclusa) sono globali.
slide 10 of
Antonello Lobianco
Funzioni
#include <iostream> using namespace std; int border = 2; // var. globale void setspace (int nrows, int ncol); // dichiarazione main() { int nrows; int ncols; cout << "Benvenuto nel programma di simulazione del modello di segregazione di Shelling " << endl; cout << "Inserire il numero di righe del modello..." << endl; cin >> nrows; cout << "Inserire il numero di colonne del modello..." << endl; cin >> ncols; setspace (nrows, ncols); // chiamata della funzione cout << "Modello programmato per gestire " << nrows << " righe e " << ncols << " colonne" << endl; return (0); } void setspace (int nrows, int ncols) { // definizione // aggiunta di due righe/colonne come bordi... nrows += border; ncols += border; cout << "Adesso abbiamo " << nrows << " righe e " << ncols << " colonne" << endl; // stampa nrows e ncols locali }
slide 11 of Antonello Lobianco
L'istruzione if
Permette l'esecuzione condizionale di un'istruzione o di un blocco di istruzioni Forma generale: if (condizione) { istruzioni... } else if (altra possibile condizione) { istruzioni alternative... } else { istruzioni se nessuna condizione passa } Ovviamente pu essere espressa in forma annidata. Nella verifica della condizione possono essere usati i consueti operatori matematici con la nota che l'operatore di uguaglianza in C++ ==, ed quindi diverso da quello si assegnazione (=) e che l'operatore di resto o modulo %.
slide 12 of Antonello Lobianco
L'istruzione if
#include <iostream> using namespace std; main() { int nrows, ncols; cout << " CIAO MONDO! " << endl; cout << "Inserire il numero di righe del modello..." << endl; cin >> nrows; cout << "Inserire il numero di colonne del modello..." << endl; cin >> ncols; if(nrows>50) { cout << "Too many rows. Please choose a maximum of 50 rows." << endl; return 0; } else if (ncols > 50) { cout << "Too many columns. Please choose a maximum of 70 columns." << endl; return 0; } else { cout << "Modello programmato per gestire " << nrows << " righe e " << ncols << " colonne." << endl; } return (0); }
slide 13 of
Antonello Lobianco
Operatori relazionali
OPERATORE > >= AZIONE maggiore di maggiore o uguale a minore di minore o uguale a uguale a diverso da
Operatori logici
OPERATORE && || ! AZIONE and or not
Il ciclo for
Viene utilizzato per ripetere un blocco di istruzioni un numero specificato di volte. for (inizializzazione; espressione di controllo; incremento){ sequenza di istruzioni } inizializzazione istruzione di assegnamento che imposta il valore iniziale della variabile di controllo del ciclo espressione di controllo espressione condizionale per la determinazione del termine del ciclo incremento la variazione della variabile di controllo da effettuare ad ogni ciclo Per uscire da un ciclo possiamo anche usare le parole chiave continue (salta al prossimo ciclo) o break (esce dal ciclo pi interno)
slide 15 of Antonello Lobianco
Il ciclo for
#include <iostream> using namespace std; void createGrid (int nrows_h, int ncols_h); main(){ int nrows, ncols; cout << "Benvenuto!" << endl; cout << "Inserire il numero di righe del modello..." << endl; cin >> nrows; cout << "Inserire il numero di colonne del modello..." << endl; cin >> ncols; createGrid(nrows,ncols); return (0); } void createGrid(int nrows_h, int ncols_h){ cout << "sto costruendo una griglia "<< nrows_h << "x" << ncols_h << ".." << endl; for(int i=0;i<nrows_h;i++){ for (int y=0;y<ncols_h;y++){ cout << "X "; } cout << endl; } }
slide 16 of
Antonello Lobianco
Il ciclo for
#include <iostream> using namespace std; int askInteger (int maxvalue=30); // 30 l'argomento di default main(){ int nrows, ncols; cout << "Benvenuto!" << endl; cout << "Inserire il numero di righe del modello..." << endl; nrows = askInteger(); // chiama con l'argomento di default cout << "Inserire il numero di colonne del modello..." << endl; ncols = askInteger(50); // chiama specificando il parametro cout << "Modello programmato per gestire " << nrows << " righe e " << ncols << " colonne" << endl; return (0); } int askInteger(int maxvalue){ int tempIntegerValue; cout << "Inserisci un valore inferiore a " << maxvalue << endl; for(;;){ // ciclo infinito cin >> tempIntegerValue; if ( tempIntegerValue <= maxvalue) break; // esce dal ciclo for se la condizione vera else cout << "Devi fornire un valore inferiore a " << maxvalue << " !!" << endl; } return tempIntegerValue; }
slide 17 of
Antonello Lobianco
Altri costrutti
Costrutti utilizzati pi raramente perch sostituibili con if o for:
istruzione switch/case
switch (espressione) { case costante1: istruzioni case costante2: istruzioni break; default: istruzioni }
ciclo while
while (espressione) istruzioni.. do{istruzioni} while {espressione} la verifica viene fatta a fine ciclo: almeno una volta l'espressione viene eseguita
slide 18 of Antonello Lobianco
ciclo do/while
Altri costrutti
#include <iostream> using namespace std; void createGrid (int nrows_h, int ncols_h); main(){ int nrows, ncols; cout << "Benvenuto!" << endl; cout << "Inserire il numero di righe del modello..." << endl; cin >> nrows; cout << "Inserire il numero di colonne del modello..." << endl; cin >> ncols; cout << "Modello programmato per gestire " << nrows << " righe e " << ncols << " colonne" << endl; createGrid(nrows, ncols); return (0); } void createGrid(int nrows_h, int ncols_h){ cout << "sto costruendo una griglia "<< nrows_h << "x" << ncols_h << ".." << endl; int i=0; while (i<nrows_h){ int y=0; while (y<ncols_h){ cout << "X "; y++; } cout << endl; i++; } }
slide 19 of Antonello Lobianco
libreria non appartenente allo standard C++ ma inclusa in tutti i moderni compilatori offre classi e funzioni template di uso generale che implementano molti algoritmi e strutture dati ben note e largamente utilizzati template perch algoritmi, contenitori (strutture dati) applicabili a qualsiasi tipologia di dati costituita da tre elementi fondamentali:
contenitori
oggetti che contengono (memorizzano) altri oggetti vector, map (array associativo), string
algoritmi
agiscono sul contenuto dei contenitori, trasformandolo, ordinandolo, ricercandolo.. ecc. es. min, random_shuffle, sort, swap iteratori
oggetti che offrono la capacit di spostarsi ciclicamente nel contenuto di un contenitore, in avanti, in indietro, ad accesso casuale..
slide 20 of Antonello Lobianco
Vettori
necessita di #include
<vector>
implementa un array (multidimensionale) dinamico, ossia che pu crescere secondo necessit rende di fatto obsoleto l'utilizzo degli array nativi del C++ (che per sono marginalmente pi performanti) alcune funzioni membro principali:
size() restituisce in numero di membri del vettore push_back() aggiunge un valore alla fine del vettore bool empty() erase (iterator i) rimuove l'elemento a cui punta l'iteratore i clear() rimuove tutti gli elementi
Vettori (codice 1 di 2)
#include <iostream> #include <algorithm> #include <vector> using namespace std; vector < vector <int> > createGrid (int nrows, int ncols, int agents); void printGrid (vector <vector <int> > pixels); int askInteger (int maxvalue=20); int main(){ int nrows, ncols, nagents; cout << "Benvenuto!" << endl; cout << "Inserire il numero di righe del modello..." << endl; nrows = askInteger(); // chiama con l'argomento di default cout << "Inserire il numero di colonne del modello..." << endl; ncols = askInteger(15); // chiama specificando il parametro cout << "Inserire il numero di agenti.." << endl; nagents = askInteger(nrows*ncols-1); cout << "Modello programmato per gestire " << nrows << " righe e " << ncols << " colonne" << endl; vector < vector <int> > pixels = createGrid (nrows, ncols, nagents); printGrid (pixels); return (0); } int askInteger(int maxvalue){ int tempIntegerValue; cout << "Inserisci un valore inferiore a " << maxvalue << endl; for(;;){ // ciclo infinito cin >> tempIntegerValue; if ( tempIntegerValue <= maxvalue) return tempIntegerValue; else cout << "Devi fornire un valore inferiore a " << maxvalue << " !!" << endl; } }
slide 22 of Antonello Lobianco
Vettori (codice 2 di 2)
vector <vector <int> > createGrid (int nrows, int ncols, int nagents){ vector < vector <int> > pixels ; for (int i=0;i<nrows;i++){ vector <int> rows (ncols, 0); pixels.push_back(rows); } //printGrid (pixels); //srand(time(NULL)); // this would re-initialise the random seed for (int i=0;i<nagents;i++) { for (;;){ int randomRow = int (0+( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(nrows-0)); // randomRow is [0,nrows[ int randomCol = int (0+( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(ncols-0)); // randomCol is [0,ncols[ if(pixels[randomRow][randomCol] == 0){ pixels[randomRow][randomCol] = 1; break; } } } return pixels; } void printGrid(vector <vector <int> > pixels){ cout << "Printing the grid.." << endl; for(int i=0;i<pixels.size();i++){ for (int y=0;y<pixels[i].size();y++){ cout << pixels[i][y] << " "; } cout << endl; } }
slide 23 of Antonello Lobianco
Stringhe STL
necessita di #include <string> alternative all'utilizzo come stringhe di vettori di char terminati da valore NULL costituiscono un tipo di dato possibile utilizzare operatori standard: = assegnamento + concatenazione == uguaglianza != disuguaglianza << output >> input Funzioni membro:
slide 24 of
Antonello Lobianco
vector < vector <char> > pixels; pixels = createGrid (nrows, ncols, nagents1, nagents2, initial1, initial2); printGrid (pixels); return (0);
slide 25 of
Antonello Lobianco
// randomRow is // randomCol is
// randomRow is // randomCol is
Antonello Lobianco
slide 27 of
Antonello Lobianco