Tre numeri - II

axpgn
Seconda puntata :D (qui la prima)

a)
In quanti modi diversi è possibile scrivere un numero $n$ come somma di tre interi non negativi?

[le somme che differiscono solo per l'ordine degli addendi sono da considerarsi uguali; per esempio $6=1+2+3$ si considera uguale a $6=3+2+1$]

b)
E quanti invece se i tre numeri sono positivi ?

Cordialmente, Alex

Risposte
dan952
Ma la richiesta b) non è la puntata precedente?

axpgn
Leggi bene: là contava anche l'ordine dei tre numeri, qui no.

Cordialmente, Alex

dan952
:smt023

axpgn
Anybody? :D

Mael93

axpgn
Eh, no … :D


Cordialmente, Alex


P.S.: È meglio mettere sotto spoiler le risposte :wink:

Mael93
[ot]scusami, modificato[/ot]
:roll: ho sbagliato qualcosa nei conti :-D intanto ci ragiono ancora :roll:

P.S. ah, ho letto solo adesso. Numero n, avevo capito numero intero n. #-o

Erich1
Salve a tutti, io avrei una soluzione algoritmica.
Pur non avendo trovato la formula che risponde al tuo quesito, con quest'approccio di forza bruta è possibile determinare - in tempo esponenziale rispetto l'input - la cardinalità dell'insieme delle soluzioni.
Intanto notiamo che n, pur se non esplicitamente richiesto come intero positivo, può essere il risultato della somma di tre interi non negativi sse è un intero non negativo, quindi restituiamo 0 nel caso in cui n sia decimale o negativo;
dopodiché parte la catena:
- per ogni n>0 esiste sempre la soluzione (n+0+0);
- per ogni n>1 esiste (n-1,1,0);
- per ogni n>2 esiste (n-2, 1, 1),(n-2,2,0);
- e così via..
Dopo aver testato tutte le combinazioni, eliminiamo le soluzioni equivalenti e contiamo quelle rimaste.

Ecco una possibile implementazione:


Ecco alcuni output d'esempio:


La soluzione al p.to b può essere ottenuta facilmente a partire da quella del p.to a eliminando dalle soluzioni quelle in cui compare lo zero.

Attendo feedback! :D

axpgn
Feedback: non funziona :-D

Cordialmente, Alex

Erich1
"axpgn":
Feedback: non funziona :-D

Cordialmente, Alex


Aglia! Nel senso che calcola l'output sbagliato o ti da qualche errore di esecuzione? :?

axpgn
Sul codice non metto bocca :D
Mentre per l'output, già per $n=7$ ce n'è uno di troppo.

Cordialmente, Alex

Erich1
Ciao, scusa se ci ho messo un po' ma sono stato impegnato e non volevo rispondere prima di avere un'altra soluzione da proporre.

L'errore dovrebbe essere nel punto in cui rimuovo le terne equivalenti (non uniche), ma direi che l'idea di base sia giusta, no?
In effetti mi hai ben indirizzato per trovare l'errore, non avevo notato che per $n=7$ si ha ['7+0+0', '6+1+0', '5+2+0', '5+1+1', '4+3+0', '4+2+1', '3+3+1', '2+2+3', '1+4+2'] con le tuple evidenziate equivalenti.

Ho dato una sistematina al codice, ed ecco una nuova lista di output:


Ecco il codice, adesso sicuramente più comprensibile:

axpgn
Bel lavoro, really! =D>

Purtroppo non serve a niente :-D … ovviamente ciò che chiedo è altro :wink:

"Erich":
In effetti mi hai ben indirizzato per trovare l'errore, ...

Ero molto bravo a trovare i bug degli altri :lol: ... ho pure fatto in tempo a notare che avevi scritto "per $n=6$" :-D

"Erich":
Ecco il codice, adesso sicuramente più comprensibile:

Scherzi, vero? Ovviamente mi riferisco a me stesso :D … sicuramente sarebbe più apprezzato nella sezione di Informatica.

Cordialmente, Alex

Erich1
"axpgn":
Bel lavoro, really! =D>

Purtroppo non serve a niente :-D … ovviamente ciò che chiedo è altro :wink:


Grazie, peccato che lo script aiuti poco nel trovare la formula: sembrerebbe una parabola da come si comporta, ma non sono ancora riuscito a trovarla :smt012

"axpgn":
[quote="Erich"]In effetti mi hai ben indirizzato per trovare l'errore, ...

Ero molto bravo a trovare i bug degli altri :lol: ... ho pure fatto in tempo a notare che avevi scritto "per $n=6$" :-D
[/quote]

Hehe, ed io che credevo d'essere stato veloce nel correggermi :shock:

axpgn
Giusto per curiosità ( :D ) , quanto ti ci vorrebbe per trovare la risposta a

$n=12345678901234567890123456789012345678901234567890123456789012345678901234567890$ ?

(sono $80$ cifre, erano $100$ ma non me le scrive tutte :lol: )

Cordialmente, Alex

Erich1
"axpgn":
Giusto per curiosità ( :D ) , quanto ti ci vorrebbe per trovare la risposta a

$n=12345678901234567890123456789012345678901234567890123456789012345678901234567890$ ?

(sono $80$ cifre, erano $100$ ma non me le scrive tutte :lol: )

Cordialmente, Alex


Be', diciamo che intanto dipende dalle risorse di calcolo che ho a disposizione; al momento il massimo di cui dispongo sono le circa (se non sbaglio) 25 milioni di operazioni binarie al secondo che mi concede il server dell'università.

Poi, provando ad azzardare un calcolo approssimativo:
a parte le relativamente poche operazioni di inizializzazione, assegnamento e simili, considerando che l'algoritmo prima calcola un numero di combinazioni compreso tra $n^2$ e $n^3$ (spendendo circa $3*n$ (da $3*2^log(n)$) operazioni per ogni terna generata) e dopodiché le confronta una ad una facendo un numero di confronti compreso tra $n^4$ ed $n^9$ (ogni confronto effettua circa $3*n$ (da $3*2^log(n)$) operazioni), per un totale di:
fissati $n^2 $r*3*n+s*3*n$

Quindi detto $C : [(n^3+n^5)*3] < C < [(n^4+n^10)*3]$ - i.e. C compreso tra caso pessimo e caso ottimo - con la possibilità di fare $25*10^6$ calcoli al secondo, e con $n=12345678901234567890123456789012345678901234567890123456789012345678901234567890$, il tempo che ci vorrebbe a calcolarlo, in secondi, è $T$ tale che:
$bot = [(1.88167*10^237)+(2.86797 * 10^395)]*3 = 8.60391 *10^395 [(operazioni)];$
$top = [(2.32305*10^316)+(8.22526 * 10^790)]*3 = 2.46758 *10^791 [(operazioni)];$
$bot
[€dit]: ho notato solo dopo che un modo più semplice per indicare il numero di operazioni necessarie C può essere: $C : [3*n^8 < C < 3*n^14]$

Questo in termini di operazioni nel tempo, significa che avendo la velocità $ lambda = 25*10^6 [(n.operazioni)/(secondi)] $ e dividendo $bot [n.operazioni]$ e $top [n.operazioni]$ per la velocità otteniamo (di tipo $[secondi]*([(operazioni)]/[(operazioni)])$):
$bot = (8.60391 *10^395) / (25*10^6) = 1.14718 * 10^388 [secondi]$
$top = (2.46758 *10^791) / (25*10^6) = 3.29010 * 10^783 [secondi]$
Passando da secondi ad ore:
$bot = (1.14718 * 10^388) / (60^2) = 3.18663 * 10^384$
$top = (3.29010 * 10^783) / (60^2) = 9.13918 * 10^779$
In termini di anni:
$bot = 1.21257 * 10^379$
$top = 3.47761 * 10^774$
$to [1.21257 * 10^379$[anni]$< T < 3.47761 * 10^774 $[anni]$]$

Va da se che, pure se avessi sbagliato qualche calcolo, non ci sarebbe nessun rischio di calcolarlo con questo algoritmo ed il potere di calcolo che ho a disposizione :lol:
Va detto però che l'algoritmo: uno non è stato rivisto né è stato progettato per funzionare velocemente, due non solo calcola la cardinalità dell'insieme, ma anche gli elementi che lo compongono :D

axpgn
Uellà che analisi! :smt023 … ma sei già laureato o ancora studi?

Beh, dai, con la "mia" formula ( :-D ) ci vuole una frazione di secondo su un notebook i5 :wink:

Il risultato è questo:

$12701315627699030625412792968805568287506985727813341*10^103+$

$+46268759843525938627242500718894554445460556381903165*10^51+$

$+7319260275825661738591939744960131331606106868871621$

(Ho dovuto scriverlo su tre righe perché non lo prende come numero unico … :? ... e non dite che ho sparato numeri a caso perché tanto nessuno può controllare [-X :lol: )

Comunque, la domanda era solo per avere un'idea di quanto potesse essere grande la differenza tra una formula diretta e un processo iterativo, non avevo altri scopi … :wink:

Un'ultima domanda (se posso permettermi): lo hai fatto per divertimento o anche come esercitazione?

Cordialmente, Alex

Erich1
"axpgn":
Uellà che analisi! :smt023 … ma sei già laureato o ancora studi?


Studio ancora, non saprei se purtroppo o per fortuna!

"axpgn":
Un'ultima domanda (se posso permettermi): lo hai fatto per divertimento o anche come esercitazione?


Certo, direi in primis per divertimento; poi non avendo quasi mai occasione di lavorare con (il semplice) python è anche un modo per non dimenticarne la sintassi ed i vari trucchetti.

Comunque avrei anche un'approssimazione della formula da proporre: risolvendo il sistema tra la generica equazione di una parabola e tre dei punti del grafo della funzione ottenuti dall'algoritmo di cui sopra, ho ottenuto:
$y = (0.0838378279215)x^2 + (0.403228765364)x + 2.07319757843$
(approssimando il risultato all'intero più vicino)

axpgn
"Erich":
Studio ancora, non saprei se purtroppo o per fortuna!

:lol: :lol:

Ho confrontato i risultati della tua funzione con i miei (usando le potenze di dieci da $10^1$ a $10^100$) e già da $10^9$ la differenza percentuale è costante: il rapporto tra la tua e la mia è $1.00605394$

Bel lavoro! :smt023

Cordialmente, Alex

Erich1
Grazie, bel quesito! :D

Secondo te per ottenere un risultato più preciso devo scegliere i tre punti del grafo $(n,F(n))$ con $n$ più grandi? O c'è un altro modo per essere più precisi?
Magari non è che potresti inviarmi la soluzione esatta in privato? :lol:

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.