Permutazioni e Gioco del 15 Dott.ssa Giovanna Rosone
Permutazione Una permutazione è un modo di combinare n oggetti distinti scambiandoli di posizione Ci sono essenzialmente due notazioni per scrivere una permutazione. Possono essere descritte in forma esplicita elencando su due righe le lettere (in ordine) e le lettere loro associate: in forma di cicli. Un ciclo è una lista di indici fra parentesi e conveniamo che rappresenti la permutazione che associa ad ogni indice nel ciclo quello successivo. Ad esempio: 1 2 1 5 5 3 2 4 4 3 1 4 3 1 2 5 2 2 5 3 4 4 3 5 1
Generare una permutazione random Dato un numero n generare una permutazione random dei numeri da 1 ad n. In pascal, la fuzione Random(n) restituisce un numero compreso tra 0 e n-1, scelto in modo casuale. Perché è necessaria la procedura Randomize, che resetta il generatore di numeri casuali? Che significa?
Generatore di numeri Pseudo-Casuali Genera una sequenza che appare casuale, ma che in realtà non lo è perchè scaturisce da un processo deterministico. Le sequenze di numeri pseudo-casuali vengono solitamente generate da un computer.
Matrice vettore 13 10 11 6 16 7 4 8 1 12 14 9 3 15 2 5 Matrice N x N 13 10 11 6 16 7 4 8 1 12 14 9 3 15 2 5 13 10 11 6 16 7 4 8 1 12 14 9 3 15 2 5 Vettore con N x N elementi
In generale: Matrice vettore 1 2 j n-1 n 1 2 i 1 2 k n*m m-1 m For i:=1 to m do for j:=1 to n do begin k:=(i-1)*n + j; vett[k] := mat[i,j]; end;
In generale: vettore 1 2 Matrice 1 2 j n-1 n 1 2 k n*m Soluzione 1: For i:=1 to m do for j:=1 to n do begin k:=(i-1)*n + j; vett[k] := mat[i,j]; end; i m-1 m Soluzione 2: For k:=1 to n*m do begin i:=(k-1) div m + 1; j:=(k-1) mod m + 1; mat[i,j] := vett[k] ; end;
Gioco del 15 Generare un vettore con numeri distinti casuali da 1 ad n*n, dove n=4 6 10 8 7 12 1 13 9 4 14 5 15 11 2 3 16 Come possiamo fare?
Prima strategia non funzionante Estraiamo un numero con la funziona random e lo mettiamo nel vettore. Esempio estraiamo il 13. Vettore di interi: V Siccome voglio numeri distinti, uso un vettore ausiliare a valori booleani, per tenere traccia dei numeri già inseriti nel vettore V. Vettore di booleani: B 13 Se B[i]=0, inserisco il numero estratto in V Se B[i]=1, non lo inserisco in V ed estraggo un altro numero. 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 Perché non funziona nel nostro caso?
2 Strategia: Procediamo per scambi Partiamo dall array ordinato ed effettuiamo degli scambi. Scambiamo ogni elemento in posizione i del vettore con un elemento nella posizione x scelta casualmente (x i). for i:=n*n downto 2 do //Per ogni elemento begin x:= random(i)+1; //Generare 1 <= x <= i scambia (v[i], v[x]); end;
Esempio for i:=n*n downto 2 do begin x:= random(i)+1; scambia (v[i], v[x]); end; //Per ogni elemento //Generare 1 <= x <= i i=16 x:=random(16)+1. Esempio x:=3+1=4 Scambia v[16] con v[4] 1 2 3 16 5 6 7 8 9 10 11 12 13 14 15 4 i=15 x:=random(15)+1. Esempio x:=13+1=14 Scambia v[15] con v[14] 1 2 3 16 5 6 7 8 9 10 11 12 13 15 14 4 Finché i=2 x:=random(2)+1. Esempio x può essere 1 o 2 Scambia v[2] con v[x]
Schema: Introduzione al Gioco del 15 Creare un vettore di 4x4=16 elementi contenente i numeri da 1 a 16 ripetuti una e una sola volta in ordine casuale (partire da un vettore ordinato); Sistemare gli elementi di tale vettore in una matrice 4x4; Visualizzare la matrice. Verifica se la matrice è ordinata.
//Inizializzazione del vettore ordinato Procedure creavettoreordinato(var vettord: vettore); Var i: integer; begin End; for i:=1 to n*n do vettord[i]:=i; Procedure creavettorerandom(var vettrand: vettore); Var i: integer; Begin End; creavettoreordinato (vettrand); for i:=n*n downto 2 do begin x:= random(i)+1; //Deve generare 1 <= x <= i end; scambia (v[i], v[x]); Procedure creamatricerandom(vettrand: vettore; var mat: matrice); Var i,j: integer; Begin End; for i:=1 to n do for j:=1 to n do //Main mat[i,j]:= vettrand[(i-1)*n + j]; //Sistema la permutazione nella matrice Begin creavettoreramdom(a); creamatriceramdom(m); visualizzamatrice (M); end;.
Gioco del 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Non tutte le permutazioni portano ad una soluzione del gioco. Il gioco è risolubile solo per le permutazioni pari.
Parità della permutazione Se la cella contenente il numero i compare prima di k numeri minori di i allora chiamiamo questa situazione un inversione di ordine k e la chiamiamo k_i. I numeri vanno letti da destra a sinistra e dall'alto in basso come se fossero in un unica striscia. Se la somma dei k_i è pari, il gioco è risolvibile, altrimenti non lo è.
Esempio 13 10 11 6 5 7 4 8 1 12 14 9 3 15 2 16 Le inversioni per ogni numero sono rispettivamente: 12, 9, 9, 5, 4, 4, 3, 3, 0, 3, 3, 2, 1, 1, e 0. La loro somma N = 59, dispari. Dunque il gioco non può essere risolto.