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