Esercizio 1. - WordPress.com

annuncio pubblicitario
CORSO DI LAUREA IN INGEGNERIA ELETTRICA
Informatica B
anno accademico 2012-2013
Prof. Danilo ARDAGNA
Esercitazione – 23.05.2013
Esercizio 1. (Elemento piu' ripetuto - funzione a singolo parametro)
Scrivere una funzione che, data una matrice, restituisce l'elemento che compare piu' spesso al suo interno.
Soluzione
Considero come elemento piu' ripetuto il primo elemento della matrice contato come ripetuto zero
volte. Dopodiche' lo confronto con il numero di volte in cui tutti gli elementi (compreso il primo) sono
compresi nella matrice. Se dal confronto risulta che un numero e' ripetuto piu' volte del precedente
elemento considerato, allora lo sostituisco. Alla fine otterro' l'elemento che compare piu' spesso.
Codice
function [elem]=elemento_piu_ripetuto(m)
elem = m(1,1);
count = 0;
[r c] = size(m);
for ii=1:r
for jj=1:c
tmp_count = sum(sum(m==m(ii,jj)));
if tmp_count>count
elem = m(ii,jj);
count = tmp_count;
end
end
end
Esecuzione
>> elemento_piu_ripetuto([1 2 3; 3 4 5; 6 7 3])
ans =
3
Esercizio 2. (Costruzione matrici - funzione a piu' parametri)
2
Scrivere una funzione che, date due matrici A e B aventi stesse dimensioni, restituisca due matrici C e D in
cui C contiene le righe di A o di B che hanno somma minore, mentre D contiene le colonne di A o di B che
hanno somma maggiore. In caso di uguaglianza tra le somme si dia priorita' alle righe/colonne della
matrice A.
Esempio:
INPUT:
| OUTPUT:
1 2 3
9 8 7 |
1 2 3
9 8 3
A=4 5 4 B=1 1 1 | C=1 1 1 D=1 1 4
1 2 3
3 2 1 |
1 2 3
3 2 3
Soluzione
Codice
function [C D] = cotruiscimatrici(A,B)
[nrighe ncolonne]=size(A); % uguale a size(B)
C=zeros(nrighe,ncolonne);
D=zeros(nrighe,ncolonne);
% determino C
for ii=1:nrighe
if sum(A(ii,:))<=sum(B(ii,:))
C(ii,:)=A(ii,:);
else
C(ii,:)=B(ii,:);
end
end
% determino D
for ii=1:ncolonne
if sum(A(:,ii))>=sum(B(:,ii))
D(:,ii)=A(:,ii);
else
D(:,ii)=B(:,ii);
end
end
Esecuzione
A =
1
4
1
2
5
2
3
4
3
9
1
3
8
1
2
7
1
1
>> B
B =
>> [C D]=costruiscimatrici(A,B)
C =
1
2
3
1
1
1
1
2
3
D =
9
8
3
1
1
4
3
2
3
2
Esercizio 3. (Fattoriale vettorizzato)
3
Data la seguente funzione per il calcolo del fattoriale. Si dica se la funzione supporta la
vettorizzazione. In caso di risposta negativa la si modifichi per supportarla.
function [f]=fact(n)
f=1;
for k=1:n
f=f*k;
end
Soluzione
La funzione fact() proposta non supporta la vettorizzazione. Cioe' non e' possibile passare alla
funzione come argomento una matrice e aspettarsi come risultato una matrice delle stesse
dimensioni di quella data avente per elementi il fattoriale degli elementi corrispondenti della matrice
originale.
Codice
function [f]=fact(n)
[r c]=size(n);
% scandisco tutti gli elementi di n
for ii=1:r
for jj=1:c
% codice originale
% sostituisco f con f(ii,jj) e n con n(ii,jj)
f(ii,jj)=1;
for k=1:n(ii,jj)
f(ii,jj)=f(ii,jj)*k;
end
end
end
Esecuzione prima della modifica
>> fact(5)
ans =
120
>> fact(2:5)
ans =
2
>> fact([2 3;4 5])
ans =
2
Esecuzione dopo la modifica
>> fact(5)
ans =
120
>> fact(2:5)
ans =
2
6
24
>> fact([2 3;4 5])
ans =
2
6
24
120 120
3
4
Esercizio 4. (Sistemi di equazioni lineari)
Si scriva uno script che chieda l'inserimento dei coefficienti e dei termini noti di un sistema di equazioni di
primo grado in M equazioni e N incognite. Dopodiche' si calcoli la soluzione del sistema. Si consideri solo
il caso in cui M e' uguale a N.
Soluzione
Il sistema puo' essere rappresentato in forma di matrice:
Dall'algebra lineare sappiamo che i valori delle incognite che corrispondono alla soluzione del sistema
sono contenuti nella matrice data dalla moltiplicazione dell'inverso della matrice dei coefficienti A per
il vettore dei termini noti.
La soluzione e' quindi S=A-1b che in Matlab equivale all'operazione di divisione sinistra: S=A\b
Codice
N=input('Inserire il numero di equazioni e di incognite: ');
for x=1:N % righe (equazioni)
for y=1:N % colonne (incognite)
A(x,y)=input(['inserire coefficiente incognita ' num2str(y)
. " "
"
"
' dell''equazione ' num2str(x) ': ']);
end
b(x)=input(['inserire termine noto equazione ' num2str(x) ': ']);
end
A
b
S=A\b'
4
5
Esecuzione
inserire
inserire
inserire
inserire
inserire
inserire
inserire
A =
b =
S =
numero di equazioni e di incognite: 2
coefficiente incognita 1 dell'equazione
coefficiente incognita 2 dell'equazione
termine noto equazione 1: 4
coefficiente incognita 1 dell'equazione
coefficiente incognita 2 dell'equazione
termine noto equazione 2: -1
1
-6
2
5
4
-1
1: 1
1: 2
2: -6
2: 5
1.2941
1.3529
Esercizio 5. (Confronti - metodo senza ciclo for)
Si scriva uno script che chiede di inserire una sequenza di N numeri, dopodiche' si inserisca un ulteriore
numero e si dica se tutti i numeri della sequenza sono minori, uguali o maggiori di tale numero.
Soluzione
Sono presenti due modi per risolvere questo problema. Il secondo modo proposto evita l'utilizzo del
costrutto for ed e' piu' efficiente e leggibile.
Codice 1
N=input('inserire N: ');
for x=1:N
a(x) = input('inserire numero: ');
end
M=input('inserire M: ');
minori=true;
maggiori=true;
uguali=true;
for x=1:N
if a(x)>M
minori=false;
uguali=false;
elseif a(x)<M
maggiori=false;
uguali=false;
else
maggiori=false;
minori=false;
end
end
if minori
disp('I numeri della sequenza sono minori del numero dato');
else
disp('I numeri della sequenza non sono minori del numero dato');
5
6
end
if maggiori
disp('I
else
disp('I
end
if uguali
disp('I
else
disp('I
end
numeri della sequenza sono maggiori del numero dato');
numeri della sequenza non sono maggiori del numero dato');
numeri della sequenza sono uguali al numero dato');
numeri della sequenza non sono uguali al numero dato');
Codice alternativo (piu' efficiente) che sostituisce il ciclo for
if sum(a<M) < N
minori = false;
end
if sum(a>M) < N
maggiori = false;
end
if sum(a==M) < N
uguali = false;
end
Esecuzione
inserire
inserire
inserire
inserire
inserire
inserire
inserire
I numeri
I numeri
I numeri
N: 5
numero: 1
numero: 2
numero: 3
numero: 4
numero: 5
M: 6
della sequenza sono minori del numero dato
della sequenza non sono maggiori del numero dato
della sequenza non sono uguali al numero dato
Esercizio 6. (Matrici logiche misteriose)
Date le seguenti matrici a e b si dica cosa stampano le seguenti istruzioni.
a=
1
4
7
2
5
8
3
6
9
b=
9
6
3
8
5
2
7
4
1
1.
a(3,1)
2.
a(8)
3.
a(a==b)
6
4.
b(a>b|b>a)
5.
c=a;c(a>b)=b(a>b).^2
6.
find(mod(a,b))
7.
[r c]=find(mod(a,b))
7
Soluzione 1
>> a(3,1)
ans =
7
L'istruzione accede al valore memorizzato nella riga 3 e colonna 1 della matrice a.
Soluzione 2
>> a(8)
ans =
6
L'istruzione accede al valore memorizzato nell'ottavo elemento della matrice. Gli elementi vengono
contati per colonna. La prima colonna ha i primi 3 elementi, la seconda colonna ha gli altri 3 e cosi'
via fino al nono elemento. In questo caso l'ottavo elemento coincide con l'elemento della seconda
riga e della terza colonna.
Soluzione 3
>> a(a==b)
ans =
5
Utilizzo il vettore logico generato dalla relazione a==b per selezionare gli elementi di a. In questo
caso il vettore logico a==b e' vero (1) soltanto per l'elemento di riga 2 e colonna 2 della matrice
(infatti e' l'unico elemento di a che e' uguale al corrispondente elemento di b). La selezione crea un
vettore che ha soltanto gli elementi selezionati. Soltanto il numero 5 in questo caso.
Soluzione 4
>> b(a>b|b>a)
ans =
9
6
3
8
2
7
4
1
Questo esercizio e' simile al precedente. Vengono selezionati tutti gli elementi di b per cui e' vero
che "a>b|b>a", cioe' che il numero di a sia maggiore di b OPPURE che il numero di b sia maggiore
di a. Questo avviene per tutti i numeri che sono diversi, quindi tutti tranne l'elemento di riga 2 e
colonna 2. Tutti gli elementi selezionati dalla relazione vengono copiati in un vettore.
Soluzione 5
>> c=a;c(a>b)=b(a>b).^2
c =
1
2
3
4
5
16
9
4
1
7
8
Copio tutti i valori della matrice a in una nuova matrice c, dopodiche' assegno a tutti i valori
di c selezionati dalla matrice logica a>b i quadrati dei corrispondenti valori di b. Ricordiamo che la
matrice logica a>b ha valore 1 (vero) per gli elementi di a che sono maggiori di b e valore 0 (falso)
negli altri casi. Il valore e' vero solo per gli elementi (2,3), (3,1), (3,2) e (3,3) della matrice, per cui
solo questi elementi saranno cambiati nella matrice c.
Soluzione 6
>> find(mod(a,b))
ans =
1
2
3
4
7
8
La funzione find restituisce gli indici dei valori non nulli passati come parametro della funzione. In
questo caso il parametro e' mod(a,b) che equivale alla matrice dei resti delle divisioni tra gli
elementi di a e di b. Il risultato finale e' l'indice degli elementi di ache non sono multipli di b (resto
nullo).
Soluzione 7
>> [r c]=find(mod(a,b))
r =
1
2
3
1
1
2
c =
1
1
1
2
3
3
Questo comando ha un effetto simile al comando precedente, ma anziche' restituire l'indice lineare
(che varia da 1 a 9 e procede colonna per colonna) restituise le due coordinate corrispondenti ai
valori non nulli. La prima coordinata e' il numero di riga, mentre la seconda coordinata e' il numero
della colonna.
Esercizio 7. (Vettori logici)
Si scriva uno script che chieda l'inserimento di una sequenza di N numeri.
Si stampino i valori dei numeri in posizione pari;
Si stampino i valori dei numeri in posizione dispari;
Si stampino i valori dei numeri pari;
Si stampino i valori dei numeri dispari.
Soluzione
Codice
clear all;
8
9
N=input('inserire N: ');
for x=1:N
a(x) = input('inserire numero: ');
end
% stampo soluzione punto 1
a(2:2:N) % stampo soluzione punto 2
a(1:2:N)
% stampo soluzione punto 3
a(mod(a,2)==0)
% stampo soluzione punto 4
a(mod(a,2)==1)
Esecuzione
inserire
inserire
inserire
inserire
inserire
inserire
ans =
ans =
ans =
ans =
N: 5
numero:
numero:
numero:
numero:
numero:
1
4
3
8
8
4
3
1
3
1
8
4
9
9
9
Esercizio 8. (Matrici rivisitate)
Scrivere un programma in linguaggio MATLAB che, data una generica matrice A precedentemente
acquisita costruisce una matrice P contenente solo le righe con indice pari della matrice A e una
matrice D contenente solo le righe con indice dispari della matrice A.
Soluzione
Codice
A=input('Inserire matrice: ')
P=A(2:2:end,:)
D=A(1:2:end,:)
Esecuzione
Inserire matrice: [0 9; 3 4; 6 4; 9 2; 0 0; 2 1]
A =
0
9
3
4
9
6
4
9
2
0
0
2
1
3
4
9
2
2
1
0
9
6
4
0
0
10
P =
Q =
Esercizio 9. (I caffe' del dipartimento)
In un dipartimento ci sono 10 persone, ognuna nell'ultima settimana ha consumato un certo numero di
caffe' memorizzati in una matrice "caffe" data.
1.
Si vuole sapere quanto deve pagare ogni persona sapendo che ogni caffe' ha un costo di 0,25 euro.
2.
Si supponga che vi sia un costo fisso di noleggio della macchinetta per fare il caffe' pari a 10 euro a
settimana. La meta' di tale costo e' divisa equamente tra i bevitori (coloro che hanno consumato
almeno un caffe') e l'altra meta' tra i bevitori che ne hanno consumato di piu' rispetto alla media. Si
dica quanto deve pagare ogni persona.
Soluzione
L'approccio che utilizziamo e' quello di creare un vettore logico che chiamiamo "bevitori" che
seleziona coloro che hanno consumato almeno un caffe'. E un altro vettore logico che chiamiamo
"superbevitori" che seleziona coloro che hanno consumato piu' caffe' rispetto alla media.
Per le medie e le somme usiamo le funzioni aggregate mean e sum precedentemente introdotte.
Codice
caffe=[0
1
4
1
2
3
0
3
0
2
0
0
6
1
1
0
0
0
0
3
0
2
3
1
2
3
0
0
0
3
0
1
3
1
2
2
0
0
0
4
0
0
2
1
2
2
0
0
0
2
0
1
2
1
1
3
0
0
0
3
0;
1;
1;
1;
2;
1;
0;
0;
1;
3]
...
...
...
...
...
...
...
...
...
% parte 1
somme_caffe = sum(caffe,2);
10
11
costi_a=somme_caffe*0.25
% parte 2
bevitori=somme_caffe~=0;
costi_b=costi_a;
costi_b(bevitori)=costi_b(bevitori)+5/sum(bevitori);
superbevitori=somme_caffe>mean(somme_caffe);
costi_b(superbevitori)=costi_b(superbevitori)+5/sum(superbevitori)
Esecuzione
costi_a =
0
1.5000
5.2500
1.7500
3.0000
3.5000
0
0.7500
0.2500
5.0000
costi_b =
0
2.1250
7.1250
2.3750
4.8750
5.3750
0
1.3750
0.8750
6.8750
Esercizio 10. (Gara automobilistica)
Dopo una gara automobilistica si ha come risultato una tabella le cui colonne rappresentano gli N
partecipanti (numerati da 1 a N) e le righe gli M giri di pista effettuati. Il valore di ogni generica cella (i,j)
della tabella rappresenta il tempo impiegato dal partecipante j per percorrere il giro i.
Supponendo che tale tabella sia stata importata in MATLAB come matrice A, si scrivano le istruzioni per:
1.
calcolare il tempo totale medio che e' stato impiegato dai partecipanti per completare la gara;
2.
determinare il vincitore della gara (cioè il numero del partecipante il cui tempo di percorrenza totale
è minore di quello degli altri partecipanti);
3.
tracciare un grafico in cui l'asse delle x rappresenta i giri compiuti dal vincitore e l'asse delle y il
tempo necessario per percorrere i giri.
A=
[0.9
1.0
1.4
1.0
1.2
0.6
0.9
1.3
0.9
0.8
0.9
0.6
1.0
1.0
0.9
0.9
1.0
0.8
0.9
1.9
1.3
1.0
1.2
1.3
1.0
1.1
0.9
1.0
1.0
1.3
1.0
1.2
1.2
1.0
0.9
1.0
1.1
0.9
1.2
0.9
1.4
1.2
0.9
1.0
1.0
0.8
1.2
2.0
1.3
0.9
0.9
0.7
1.0
0.9
0.9;
1.1;
1.1;
1.2;
1.2;
1.1;
1.0;
1.0;
1.0;
...
...
...
...
...
...
...
...
...
11
12
1.2
1.3
3.2
1.4
1.2
0.9
1.3]
Soluzione punto 1
tempomedio=mean(sum(A))
Soluzione punto 2
vincitore=find(sum(A)==min(sum(A))
Soluzione punto 3
[M N]=size(A);
x=1:M;
y=A(:,vincitore);
plot(x,y)
Esercizio 11. (Crivello di Eratostene)
Si scriva uno script che trovi tutti i numeri primi compresi tra 2 e N utilizzando il metodo del Crivello di
Eratostene. Secondo questo metodo bisogna scrivere tutti i numeri da 2 a N. Dopodiche' partendo da 2
fino ad arrivare a N si rimuovono dalla sequenza tutti i multipli del numero considerato, ad eccezione del
numero considerato. Alla fine nella sequenza resteranno soltanto i numeri primi.
Soluzione
Codice
N=input('Inserire N: ');
% creo la sequenza
a=2:N;
% considero tutti i numeri da 2 a N-1: rimuovo i loro multipli
for ii=2:N-1
multipli=mod(a,ii)==0;
diversi=a~=ii;
a(multipli & diversi) = [];
end
Soluzione alternativa
Utilizzo un vettore di N elementi booleani. Ogni elemento vale true se e' presente nella sequenza,
vale false se e' stato cancellato dalla sequenza. Prima di utilizzare il metodo del crivello tutti i numeri
vengono inizializzati a true ad eccezione di 1 che non e' un numero primo per convenzione.
Codice
clear all;
N=input('inserire N: ');
a(2:N)=true; % assumo inizialmente che tutti i numeri siano primi
a(1)=false; % 1 non e' un numero primo
% marco come non primi i numeri multipli del numero iniziale
for x=2:N
a(2*x:x:N) = false; % il 2*x esclude il numero iniziale
end
% stampo risultato
find(a)
12
13
Esecuzione
inserire N: 30
ans =
2
3
5
7
11
13
17
19
23
29
Esercizio 12. (minore complementare)
Data una matrice quadrata di dimensioni M x M e scelto un elemento in posizione (r, c), il suo minore
complementare è dato dalla matrice che si ottiene eliminando la riga r e la colonna c dalla matrice di
partenza.
Ad esempio, data la seguente matrice:
A=[0
0
0;
"
"
"
0
1
2;
"
"
"
3
4
5;]"
"
"
"
"
Il minore complementare della cella in posizione <0, 1> contenente il valore 0 è dato dalla seguente
matrice:
A=[0
"
"
"
3
2; ...
5;]"
Implementare la funzione che restituisce il minore di una matrice dati un numero di riga e di colonna
Soluzione
Codice
function [minore]=minoreComplementare(m,i,j)
minore = m;
minore(i,:) = []; % eliminiamo la riga i-esima
minore(:,j) = []; % eliminiamo la colonna j-esima
13
Scarica