Sudoku per deficienti

di il
11 risposte

Sudoku per deficienti

Domandina scema. Vorrei scrivere un risolutore del sudoku molto stupido, semplicemente prova ogni singola combinazione (comprese quelle no-sense tipo 1 1 1 1 1 1 1 1 1 etc) fino a trovare la soluzione. Per fare ciò mi sono accorto che servono 9^81/2 tentativi in media, numero molto molto grande. C'è un modo per quantificare quanto tempo ci metterebbe il mio pc a risolverlo?

11 Risposte

  • Re: Sudoku per deficienti

    Ammesso che la tua stima sia corretta normalmente si trasforma in base 10, si stima il tempo di una operazione in microsecondi, fai la divisione
  • Re: Sudoku per deficienti

    Secondo me, ad ogni tentativo di inserimento in casella devi verificare se lo schema risulta valido, o meglio se quell'inserimento è possibile: in questo modo riduci drasticamente il tempo, ci *solo* alcuni miliardi di schemi possibili, che però si riducono considerando le cifre dello schema di partenza).
  • Re: Sudoku per deficienti

    enricoscarsissimo ha scritto:


    Vorrei scrivere un risolutore del sudoku molto stupido, semplicemente prova ogni singola combinazione (comprese quelle no-sense tipo 1 1 1 1 1 1 1 1 1 etc) fino a trovare la soluzione.
    Anche mettendola in questi termini non la farei comunque tanto facile!
  • Re: Sudoku per deficienti

    Non a caso ho chiesto prima di provare effettivamente a implementare il codice
    cmq qualcuno sa dirmi se si è mai scontrato con numeri del genere? E se un pc normale riesce a completare le operazioni in tempi ragionevoli? (non piu di 5 minuti direi)
  • Re: Sudoku per deficienti

    Se controlli la correttezza di ogni inserimento le soluzioni le puoi trovare in meno di un secondo
  • Re: Sudoku per deficienti

    Qualche tempo fa ho creato un programma che cerca di risolvere uno schema utilizzando una serie di algoritmi che simulano varie strategie logiche, e se non vi riesce lo risolve con la "forza bruta". In ogni caso disattivando le varie strategie logiche, il programma andando a tentativi risolve i sudoku nel giro di qualche decimo di secondo.
    Questo per dirti che molto dipenderà da come imposterai il tutto!
  • Re: Sudoku per deficienti

    9^81/2 e' circa 10^77

    Supponendo di avere un cluster di 1.000.000.000 (UN MILIARDO) di computer a 100GHz (100.000.000.000 Hz), e supponendo di testare una soluzione ad OGNI ciclo di clock, ti servono:

    10^77/(10^9*10^11) = 10^77/10^20 = 10^57 secondi

    che corrispondono a circa

    - 10^51 ANNI (sarebbe circa 2*10^51, ma a questi livelli, moltiplicare per 2 serve decisamente a poco ), pari a
    - 10^42 MILIARDI DI ANNI

    Se vuoi usare un cluster di calcolatori ad 1 THz, ti basta DECREMENTARE di 1 gli esponenti indicati sopra.

    Se vuoi usare un MEGA-CLUSTER-GALATTICO composto da MILLE MILIARDI di computer a 1 THz, ti basta DECREMENTARE di 4 (QUATTRO) gli esponenti di cui sopra.

    Tenendo presente che le stime dicono che un protone si trasforma in un neutrone in circa 10^33 anni

    c'e' tutto il tempo affinche' l'INTERA MATERIA dell'universo conosciuto e non si trasformi in puri neutroni ANCHE considerando il MEGA-CLUSTER-GALATTICO

    E che evaporino pure i buchi neri, almeno quelli piu' piccoli, operazione che avviene in 10^65 anni, se si considerano anche quelli grandi (quelli al centro delle galassie, di dimensione MILIARDI di soli)



    Direi, a naso, che il tuo approccio non sia molto efficiente
    E povero il tuo PC
  • Re: Sudoku per deficienti

    Lol, a questo punto mi viene il dubbio sia veramente questa la complessità dell'algoritmo. Se qualcuno sa rispondere, l'algoritmo prova ogni singola combinazione di numeri (da 1 a 9) in 81 spazi (i 9x9 del sudoku). A pensarci è come se dovesse contare da 1111(x 81 volte) fino a 999999(x 81 volte)
  • Re: Sudoku per deficienti

    In realta', le tue valutazioni sul numero di possibili configurazioni e' decisamente sovvrastimato/sbagliato

    https://it.wikipedia.org/wiki/Sudok
    http://oeis.org/A10773

    Puoi ragionare in questo modo:

    1) il sudoku e' composto da 3x3 quadrati di 3x3 elementi

    2) ogni elemento contiene UNA PERMUTAZIONE dei numeri da 1 a 9, quindi ci sono 9! = 362880 possibili permutazioni per ogni possibile elemento

    3) poiche ci sono 9 elementi, ed ognuno puo' avere 9! configurazioni, in totale ci sono, AL LIMITE, 9*9! =

    3265920

    possibili configurazioni da testare

    Un numero DECISAMENTE piu' abbordabile

    In ogni caso, ci sono un bel po' di configurazioni non ammesse perche', ad esempio, sulla stessa riga/colonna ci devono essere TUTTE cifre diverse. Quindi, il numero di configurazioni da testare sono MOLTE MENO di 3265920.

    Anzi, si puo' fare un po' meglio:

    1) il primo elemento (in alto a sinistra) e' una qualunque possibile permutazione, ma l'ultimo (in basso a destra) ha un'unica configurazione possibile, quindi il numero di configurazioni totali sono AL LIMITE 8*9!

    2903040

    Ma si puo' fare ancora meglio considerando che a mano mano che si riemniono gli elementi, il numero delle configurazioni possibili per gli elementi rimanenti si riduce molto velocemente (infatti, per l'ultimo e' SOLO UNA).

    ================================================================================

    Nota: su wikipedia dicono che il numero totale di soluzioni e':

    6670903752021072936960

    mentre il numero di configurazioni UNICHE (escludendo rotazioni, riflessioni, permutazioni) e'

    5472730538

    Dovro' controllare, ma a naso direi che questi numeri non possono essere giusti:

    1) la fattorizzazione di 6670903752021072936960 e':

    2^20 * 3^8 * 5 * 7 * 27704267971

    Da dove salta fuori questo 27704267971 ???

    2) la fattorizzazione di 5472730538 e':

    2 * 11^2 * 23 * 983243

    di nuovo, da dove salta fuori questo 983243 ???

    3) il sudoku puo' essere visto anche come un oggetto algebrico, ad esempio un GRUPPO, e le configurazioni UNICHE sono dei particolari SOTTOGRUPPI.

    Ci sono dei TEOREMI di algebra astratta che dicono che il numero di elementi di un sottogruppo DIVIDE il numero di elementi del GRUPPO, cosa che non avviene con i numeri indicati in Wikipedia.

    Direi che bisogna approfondire su testi un po' piu' seri.
  • Re: Sudoku per deficienti

    Se per wiki (se ho contato bene gli zeri) sono 6*10^20 soluzioni, considerando solo soluzioni sensate (ovvero in ogni quadretto da 3x3 ci vanno cifre diverse) allora temo che le mie siano ancora di più. Il mio algoritmo brutal force vorrebbe provare un mucchio di combinazioni irragionevoli (che non sono neanche permutazioni che io sappia) ,comprese quelle di 81 uni, 80 uni e un 2, 80 uni e un 2 in un'altra posizione e così via. Chiaramente potrei fare di meglio ma con le mie competenze non mi avvicinerei neanche lontanamente all'ottimalità
  • Re: Sudoku per deficienti

    Sulla scia dell'esercizio sul quadrato magico ho tirato giù questa soluzione
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
    #define DIM 3
    void generazione_p(int matp[][DIM]);
    void inizializza_p(int matp[][DIM]);
    void inizializza_G(int matG[][DIM*DIM]);
    void stampa_P(int matp[][DIM]);
    void stampa_G(int matG[][DIM*DIM]);
    int confronto(int num,int matp[][DIM]);
    void genera_G(int matp[][DIM],int matG[][DIM*DIM],int ,int );
    int verifica(int matG[][DIM*DIM]);
    
    
    int main(){
    srand(time(NULL));
    int matG2[][DIM*DIM] = { {5,3,4,6,7,8,9,1,2},{6,7,2,1,9,5,3,4,8},{1,9,8,3,4,2,5,6,7},{8,5,9,7,6,1,4,2,3},{4,2,6,8,5,3,7,9,1},{7,1,3,9,2,4,8,5,6},{9,6,1,5,3,7,2,8,4},{2,8,7,4,1,9,6,3,5},{3,4,5,2,8,6,1,7,9}};
    int matp[DIM][DIM];
    int i,j,flag = 0;
    int matG[DIM*DIM][DIM*DIM];
    inizializza_p(matp);
    inizializza_G(matG);
    	while(flag==0){
    		for(j=0; j<DIM; j++)
    			for(i=0; i<DIM; i++){			//genera matrice 9*9
    				generazione_p(matp);
    				genera_G(matp,matG,i,j);
    			}
    		if(verifica(matG)==1){
    			stampa_G(matG);
    			flag =  1;
    		}
    		else
    			inizializza_G(matG);
    	//printf("%d",verifica(matG2));	
    	}
    }
    
    
    
    
    void genera_G(int matp[][DIM],int matG[][DIM*DIM],int i,int j){
    int m,n,cont,cont2;
    	for(m=i*DIM,cont=0; cont<DIM; cont++,m++)
    		for(n=j*DIM,cont2=0; cont2<DIM; cont2++,n++)
    			matG[m][n] = matp[cont][cont2];
    }
    
    
    
    
    
    
    void generazione_p(int matp[][DIM]){
    	int num,i,j;
    	inizializza_p(matp);
    	for(i=0; i<DIM; i++)
    		for(j=0; j<DIM; j++){
    			num = rand() % (DIM*DIM) + 1;
    			while(confronto(num,matp)==1)
    					num = rand() % (DIM*DIM) + 1;
    			matp[i][j] = num;
    		}
    }
    
    
    void inizializza_p(int matp[][DIM]){
    	int i,j;
    	for(i=0; i<DIM; i++)
    		for(j=0; j<DIM; j++)
    			matp[i][j]=0;
    }
    
    void inizializza_G(int matG[][DIM*DIM]){
    	int i,j;
    	for(i=0; i<DIM*DIM; i++)
    		for(j=0; j<DIM*DIM; j++)
    			matG[i][j]=0;
    }
    
    void stampa_P(int matp[][DIM]){
    	int i,j;
    	for(i=0; i<DIM; i++){
    		for(j=0; j<DIM; j++)
    			printf("%d ",matp[i][j]);
    		printf("\n");
    	}
    }
    
    void stampa_G(int matG[][DIM*DIM]){
    	int i,j;
    	for(i=0; i<DIM*DIM; i++){
    		for(j=0; j<DIM*DIM; j++)
    			printf("%d ",matG[i][j]);
    		printf("\n");
    	}
    }
    int confronto(int num,int mat[][DIM]){
    	int i,j;
    	for(i=0; i<DIM; i++){
    		for(j=0; j<DIM; j++)
    			if(num == mat[i][j])
    				return 1;
    	}
    	return 0;
    
    }
    
    int verifica(int matG[][DIM*DIM]){
    	int somma1=0,i,j,somma2;
    	for(i=0,j=0; i<DIM*DIM; i++)			//valore check 
    		somma1 =  somma1 + matG[j][i];
    		
    	for(i=0; i<DIM*DIM; i++){			//confronto righe con somma
    		for(j=0,somma2=0; j<DIM*DIM; j++)
    			somma2=somma2+matG[i][j];
    		if(somma2!=somma1)
    			return 0;
    	}
    
    	for(i=0; i<DIM*DIM; i++){			//confronto colonne con somma
    		for(j=0,somma2=0; j<DIM*DIM; j++)
    			somma2=somma2+matG[j][i];
    		if(somma2!=somma1)
    			return 0;
    	}
    	return 1;
    }
    Ho usato matG2 per assicurarmi che la funzione verifica funzioni, non sono certo che costruisca le matrici 9x9 in modo corretto ma avevo fatto delle prove e dovrebbe funzionare. Ammesso che funzioni purtroppo non trova soluzioni in tempi utili
Devi accedere o registrarti per scrivere nel forum
11 risposte