C e Maltab: esercizi sulle matrici
Transcript
C e Maltab: esercizi sulle matrici
Esercitazione: 19/06/2015 1. Date due matrici S e T di uguali dimensioni, definiamo la somma delle differenze assolute: SAD(T, S) = numRighe X numCol X i=1 |S(i, j) − T(i, j)| j=1 • Scrivere un programma C che implementa l’algoritmo per il template matching: (a) Il programma acquisisce una matrice A 5x5 e poi una seconda matrice B 2x2. (b) Il programma individua la sottomatrice 2x2 di A che minimizza la somma delle differenze assolute mostrando a video le coordinate in A dell’elemento in alto a sinistra della sottomatrice individuata. SAD=5& SAD=9& &1 2 3 # A = $$4 5 6!! $%7 8 9!" SAD=3& &2 5# B=$ ! %7 7 " Output%=%(2,%1)% SAD=6& • Scrivere una funzione Matlab templateMatching che riceve in ingresso due matrici A e B, e restituisce una coppia di valori (x, y) nel modo seguente: – Se B ha più righe o più colonne di A, (x, y) è pari a (-1, -1). – Altrimenti, (x, y) è la posizione del primo elemento della sottomatrice S di A con le stesse dimensioni di B che minimizza il valore di SAD(T, B). • Scrivere inoltre uno script che: – Richiede all’utente di inserire due matrici. – Invoca la funzione templateMatching su tali matrici e stampa a video il risultato ottenuto. 1 Soluzione C #include < stdio .h> #include < stdlib .h> # define DIMA 5 # define DIMB 2 void main () { int a[DIMA ][ DIMA], b[DIMB ][ DIMB ]; // def matrici int sad , minsad ; int i, j, k, l, mini , minj; // carico matrici_________________________________ for(i=0;i<DIMA;i++) for(j=0;j<DIMA;j++) scanf ("%d", &a[i][j]); for(i=0;i<DIMB;i++){ for(j=0;j<DIMB;j++){ scanf ("%d", &b[i][j]); // _________________________________________________ // DIMA -DIMB e’ di quanto posso muovermi for(i = 0; i <= DIMA -DIMB; i++){ for(j=0; j <= DIMA -DIMB; j++){ // calcolo la sad sad = 0; for(k=0; k < DIMB; k++) for(l=0; l < DIMB; l++) sad = sad + abs(a[i+k][j+l] - b[k][l]); if((i==0 minsad mini = minj = } && j==0) || sad < minsad ){ = sad; i; j; } } printf (" Posizione trovata : (%d, %d)\n", mini , minj ); } 2 Soluzione Matlab f u n c t i o n [ x , y ] = templateMatching (A, B) [ ra , ca ] = s i z e (A, 1 ) ; [ rb , cb ] = s i z e (B, 1 ) ; i f rb > r a | | cb > ca x = −1; y = −1; else dr = r a − rb + 1 ; dc = ca − cb + 1 ; f o r i i = 1 : dr f o r j j =1: dc % estrazione della sottomatrice A1 = A( i i : i i +rb −1 , j j : j j +cb −1) ; sad = abs ( sum ( sum (A1−B) ) ) ; i f i i ==1 && j j ==1 | | sad < minsad minsad = sad ; x = ii ; y = jj ; end end end end 3 2. Scrivere un programma in C in grado di determinare se in una matrice 3x3 acquisita da tastiera vi sono sottomatrici quadrate (di dimensioni qualsivoglia) in cui la somma degli elementi è nulla. In particolare: (a) prima il programma acquisisce da tastiera i valori della matrice 3x3 (b) e poi inizia la ricerca delle sottomatrici nulle partendo dalla sottomatrice di dimensioni 1x1 fino alla quella 3x3. (c) Per ogni sottomatrice a somma nulla il programma stampa a video le coordinate dell’elemento in alto a sinistra. Relizzare uno script Matlab che: (a) chieda all’utente il nome del file .mat contenente una matrice quadrata (b) carichi tale matrice verificando che sia effettivamente una matrice quadrata (in caso non lo sia si generi un errore) (c) come nel caso di C ricerchi tutte le sottomatrici nulle di tutte le dimensioni e per ogni sottomatrice nulla stampi a schermo le coordinate dell’elemento in alto a sinistra. 4 Soluzione C #include < stdio .h> # define MAXD 3 void main (){ int matr[MAXD ][ MAXD ]; int i, j, k, h, currDim , somma ; // acquisizione matrice____________ for(i = 0; i < MAXD; i++) for(j = 0; j < MAXD; j++) scanf ("%d", &matr[i][j]); // __________________________________ // devo considerare tuttel le possibili dimensioni for( currDim = 1; currDim <= MAXD; currDim ++){ printf (" Matrici di dimensione %d:\n", currDim ); // per non andare oltre la dim della matrice for(i = 0; i + currDim <= MAXD; i++){ for(j = 0; j + currDim <= MAXD; j++){ somma = 0; for(k=0; k < currDim ; k++) for(h=0; h < currDim ; h++) somma = somma + matr[i+k][j+h]; if( somma == 0) printf ("%d ,%d\n", i, j); } } } } 5 Soluzione Matlab clear ; f i l e n a m e = i n p u t ( ' I n s e r i r e nome f i l e : ' , ' s ' ) ; matr = l o a d ( f i l e n a m e ) ; dim = l e n g t h ( matr ) ; a s s e r t ( a l l ( dim==s i z e ( matr ) ) ) ; f o r currDim = 1 : dim d i s p ( [ ' M a t r i c i d i d i m e n s i o n e ' num2str ( currDim ) ] ) ; f o r i i = 1 : dim − currDim + 1 f o r j j = 1 : dim − currDim + 1 submatr=matr ( i i : i i +currDim −1 , j j : j j +currDim −1) ; i f sum ( submatr ( : ) )==0 d i s p ( [ num2str ( i i ) ' , ' num2str ( j j ) ] ) ; end end end end 6 3. Scrivere un programma in C e in Matlab che riceve in ingresso il contenuto di una matrice quadrata 5x5 di interi. Il programma calcola e visualizza le coordinate dei massimi locali della matrice. Il massimo locale è definito come un elemento della matrice i cui elementi adiacenti sono tutti minori o uguali ad esso. Per esempio 2 7 61 6 M =6 65 49 4 4 9 9 8 2 3 6 3 2 8 2 4 1 4 4 3 1 37 7 67 7 35 1 ha come output: M[1,1] = 9 M[2,1] = 9 M[2,4] = 6 M[3,0] = 9 M[4,2] = 8 7 Soluzione C #include < stdio .h> # define MAX 5 int main (){ int matrice [MAX ][ MAX ]; int i, j, k, h, isMax ; // carico la matrice for(i=0; i < MAX; i++) for(j=0; j < MAX; j++) scanf ("%d", & matrice [i][j]); for(i=0; i<MAX; i++) for(j=0; j<MAX; j++){ isMax = 1; for(k= -1; k <2; k++) for(h= -1; h <2; h++) if( isMax && i+k >= 0 && i+k < MAX && j+h >= 0 && j+h < MAX && // elemento interno matrice [i][j] < matrice [i+k][j+h]){ isMax = 0; } if( isMax ) printf ("M[%d %d] = %d \n", i,j, matrice [i][j]); } } 8 Soluzione Matlab clear ; f i l e n a m e = i n p u t ( ' I n s e r i r e nome f i l e : ' , ' s ' ) ; matr = l o a d ( f i l e n a m e ) ; %% a s c i i f i l e o n l y dim = s i z e ( matr , 1 ) ; a s s e r t ( a l l ( dim==s i z e ( matr ) ) ) ; f o r i i = 1 : dim f o r j j = 1 : dim l o w i i = max( i i −1 , 1 ) ; l o w j j = max( j j −1 , 1 ) ; h i g h i i = min ( i i +1, dim ) ; h i g h j j = min ( j j +1, dim ) ; i f a l l ( matr ( l o w i i : h i g h i i , l o w j j : h i g h j j ) <= matr ( i i , j j ) ) d i s p ( [ 'M( ' num2str ( i i ) ' , ' num2str ( j j ) ' ) = ' num2str ( matr ( i i , j j ) ) ] ) ; end end end 9 4. Si realizzi in linguaggio C un programma in grado di simulare il movimento di un topolino. Data una matrice Q, di dimensione N x N, che descrive le caratteristiche di una certa area: in ciascuna cella Q(x,y) della matrice vi è la quota del quadratino di superficie posto alle coordinate (x,y). A partire da una posizione iniziale del topolino, (x0,y0), si stampino le coordinate di tutti i quadratini toccati dal topolino se esso segue le seguenti regole di movimento: • il topolino si sposta ad ogni passo di un solo quadratino, nelle 8 direzioni possibili; • il topolino sceglie il quadratino su cui muoversi determinando il quadratino di quota massima tra gli 8 adiacenti; • se tutti i quadratini adiacenti sono ad una quota inferiore (oppure uguale) rispetto al quadratino attuale, il topolino si ferma. 10 #include < stdio .h> # define N 5 typedef struct { int riga; int colonna ; } t_pos ; int main (){ int lab[N][N]; t_pos pos; int esci =0, trovato , x, y; pos.riga =0; pos. colonna =0; while (esci != 1){ printf ("\n(%d ,%d)",prox.riga , prox. colonna ); trovato =0; for(x=pos.riga -1; x <= pos.riga +1; x++) for(y=prox.colonna -1; y <= prox. colonna +1; y++) if(! trovato && x >=0 && x<N && y >=0 && y<N && x!= prox.riga && y!= prox. colonna && lab[x][y] > lab[prox.riga ][ prox. colonna ]){ prox.riga=x; prox. colonna =y; trovato = 1; } if (! trovato ) esci =1; } } 11