Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - [aiuto] Programma C
Forum - C/C++ - [aiuto] Programma C

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
FireAxe (Normal User)
Newbie


Messaggi: 5
Iscritto: 14/02/2008

Segnala al moderatore
Postato alle 17:28
Giovedì, 14/02/2008
Dunque io devo fare questo:

Far calcolare ad un programma  quanti termini sono necessari perche'
|a(n-1)/a(n) - g | < epsilon con:
epsilon = 1.E-5
g vale 0.618....
e a(n-1)/a(n) che è il rapporto tra il valore i-esimo di fibonacci e il suo precedente.

io ho fatto il codice C cosi':

Codice sorgente - presumibilmente C

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. #define epsilon 1.e-12
  6.  
  7. int fibonacci_iterativo(int val);
  8.  
  9. int main()
  10. {
  11.    
  12.     double a, b, c, g;
  13.     int  i, val, count;
  14.  
  15.     printf("Epsilon vale: %.12lf \n", epsilon);
  16.     g = (sqrt(5.0) - 1 )/2;
  17.     printf("G Vale: %.12f \n", g);
  18.    
  19.  
  20.     i=1;
  21.     a = fibonacci_iterativo(i);
  22.     b = fibonacci_iterativo(i-1);
  23.     c = ((b)/a);
  24.     while ((abs(c-g)) < epsilon )
  25.      {
  26.       count = count +1;
  27.       i=i+1;
  28.       a = fibonacci_iterativo(i);
  29.       b = fibonacci_iterativo(i-1);
  30.       c = ((b)/a);
  31.      }
  32.      
  33.  
  34.      printf("Contatore: %d\n", count);
  35. }
  36. /*Funzione Iterativa Fibonacci*/
  37.  
  38. int fibonacci_iterativo(int val)
  39.  {
  40.   int d, e, f;
  41.  
  42.   d=0;
  43.   e=1;
  44.  
  45.   while (val > 0)
  46.   {
  47.     f = d + e;
  48.     d = e;
  49.     e = f;
  50.     val = val-1;
  51.   }
  52.  
  53.   return (d);
  54.  }



Ho fatto la funzione iterativa per il calcolo del valore di fibonacci e il suo precedente, e ho provato a fare il while per fare il confronto con il segno < e fare un count per aumentare di 1 ad ogni valore minore dell'epsilon dal primo valore della successione... solo che nn riesco ad andare avanti :(

Help Me pls

Pierotofy: messo a posto il tag code

Ultima modifica effettuata da pierotofy il 15/02/2008 alle 13:58
PM Quote
Avatar
bangirasu (Normal User)
Rookie


Messaggi: 39
Iscritto: 15/08/2007

Segnala al moderatore
Postato alle 3:14
Venerdì, 15/02/2008
Hai fatto un po' di errori...
1) Non devi dimenticare di inizializzare count!
Penso che vada inizializzato a 1.


2) Non puoi usare abs!! abs calcola il valore assoluto solo degli interi, con i float o i double devi usare fabs!
Codice sorgente - presumibilmente C

  1. #include <stdio.h>
  2. int main(){
  3.         double i=10.25;
  4.         printf("%i\n", abs(i));
  5.         printf("%f\n", abs(i));
  6.         printf("%f\n", fabs(i));
  7.         return 0;
  8. }


Questo stamperà:
10
0.000000
10.250000


3) Errore Logico in questo while:
   while ((fabs(c-g)) < epsilon )
Il programma come lo hai fatto tu non entrerà mai nel while perchè (fabs(c-g)) vale 0.618 ed è maggiore di epsilon che vale 1.e-12

QUello che devi fare è devi ciclare finchè (fabs(c-g)) > epsilon  !
quando succederà che (fabs(c-g)) < epsilon  si uscirà dal while e bisognerà stampare il valore do count



Penso che se non ti fossi dimenticato di inizializzare count ti saresti accorto del fatto che le istruzioni all'interno del while non venivano mai eseguite. Invece non avendolo inizializzato alla fine, nella stampa, ritrovavi un valore di count diverso da zero e quindi hai pensato che il count fosse stato incrementato dall'istruzione nel while.

PS: bravo per aver scelto una versione di fibonacci iterativa in quanto ha complessità minore di quella ricorsiva

LINK complessità fibonacci ricorsivo e iterativo
http://www.valentinocondoluci.it/appunti/algoritmi/comples ...

Ultima modifica effettuata da bangirasu il 15/02/2008 alle 3:28
PM Quote
Avatar
FireAxe (Normal User)
Newbie


Messaggi: 5
Iscritto: 14/02/2008

Segnala al moderatore
Postato alle 11:35
Venerdì, 15/02/2008
Testo quotato

Postato originariamente da bangirasu:

Hai fatto un po' di errori...
1) Non devi dimenticare di inizializzare count!
Penso che vada inizializzato a 1.




Vero, mi ero scordato. Ma se io utilizzo la variabile i che mi si incrementa invece di utilizzare una nuova variabile count?

Testo quotato


2) Non puoi usare abs!! abs calcola il valore assoluto solo degli interi, con i float o i double devi usare fabs!
Codice sorgente - presumibilmente C

  1. #include <stdio.h>
  2. int main(){
  3.         double i=10.25;
  4.         printf("%i\n", abs(i));
  5.         printf("%f\n", abs(i));
  6.         printf("%f\n", fabs(i));
  7.         return 0;
  8. }


Questo stamperà:
10
0.000000
10.250000



Perfetto, nn ne ero a conoscenza!

Testo quotato


3) Errore Logico in questo while:
   while ((fabs(c-g)) < epsilon )
Il programma come lo hai fatto tu non entrerà mai nel while perchè (fabs(c-g)) vale 0.618 ed è maggiore di epsilon che vale 1.e-12

QUello che devi fare è devi ciclare finchè (fabs(c-g)) > epsilon  !
quando succederà che (fabs(c-g)) < epsilon  si uscirà dal while e bisognerà stampare il valore do count



Eh, infatti se lasciavo il simbolo che avevo messo io il while nn partiva  mi dava count 1 perchè era già maggiore. Ora funziona il while.

Testo quotato



Penso che se non ti fossi dimenticato di inizializzare count ti saresti accorto del fatto che le istruzioni all'interno del while non venivano mai eseguite. Invece non avendolo inizializzato alla fine, nella stampa, ritrovavi un valore di count diverso da zero e quindi hai pensato che il count fosse stato incrementato dall'istruzione nel while.



Infatti, senza il count inizializzato mi dava un numero immenso... e poi all'improvviso un count sempre a 47 anche se cambiavo la epsilon.

Ecco il Codice modificato che sembra funzionare:

Codice sorgente - presumibilmente C

  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. #define epsilon 1.e-5
  5.  
  6. int fibonacci_iterativo(int val);
  7.  
  8. int main()
  9. {
  10.    
  11.     double a, b, c, g, h;
  12.     int  i, val, count=0;
  13.  
  14.     printf("Epsilon vale: %.12lf \n", epsilon);
  15.     g = (sqrt(5.0) - 1 )/2;
  16.     printf("G Vale: %.12f \n", g);
  17.    
  18.  
  19.     i=1;
  20.     a = fibonacci_iterativo(i);
  21.     b = fibonacci_iterativo(i-1);
  22.     c = ((b)/a);
  23.     /*h = fabs(c-g);
  24.     printf ("c-g vale: %.12lf \n", h);*/ /*Operazione in più solo per verificare che h sia realmente c-g*/
  25.     while ((fabs(c-g)) > epsilon )
  26.      {
  27.       count = count + 1;
  28.       i=i+1;
  29.       a = fibonacci_iterativo(i);
  30.       b = fibonacci_iterativo(i-1);
  31.       c = ((b)/a);
  32.       /*h = fabs(c-g);
  33.       printf("C: %.12lf \n", c);
  34.       printf("G: %.12lf \n", g);
  35.       printf ("c-g vale: %.12lf \n", h);*/ /*Controllo per h*/
  36.      }
  37.      
  38.  
  39.      printf("Contatore: %d\n", count);
  40. }
  41.  
  42. /*Funzione Iterativa Fibonacci*/
  43.  
  44. int fibonacci_iterativo(int val)
  45.  {
  46.   int d, e, f;
  47.  
  48.   d=0;
  49.   e=1;
  50.  
  51.   while (val > 0)
  52.   {
  53.     f = d + e;
  54.     d = e;
  55.     e = f;
  56.     val = val-1;
  57.   }
  58.  
  59.   return (d);
  60.  }



Grazie mille per l'aiuto, prova a vedere questo codice come ti sembra :) :k:

PM Quote
Avatar
bangirasu (Normal User)
Rookie


Messaggi: 39
Iscritto: 15/08/2007

Segnala al moderatore
Postato alle 12:49
Venerdì, 15/02/2008
Testo quotato

Postato originariamente da FireAxe:

Testo quotato

Postato originariamente da bangirasu:

Hai fatto un po' di errori...
1) Non devi dimenticare di inizializzare count!
Penso che vada inizializzato a 1.




Vero, mi ero scordato. Ma se io utilizzo la variabile i che mi si incrementa invece di utilizzare una nuova variabile count?



Si potevi benissimo omettere la variabile count e usare i dato che ad ogni ciclo viene incrementata.
Adesso il programma funziona
:k:

PM Quote
Avatar
FireAxe (Normal User)
Newbie


Messaggi: 5
Iscritto: 14/02/2008

Segnala al moderatore
Postato alle 13:55
Venerdì, 15/02/2008
Ho provato a vedere:

Se uso la i il contatore mi arriva a 13 (per esempio)
Se invece metto anche il Count mi arriva a 12

se nn ho capito male, con la i mi mostra anche il valore che supera e con il Count mi mostra quelli precedenti giusto?

Cmq ora sono a questo punto, ho messo tutto in funzione, devo fare il calcolo sia con funzione iterativa che ricorsiva, ora la mia domanda è: confrontare come cresce il
tempo di calcolo nelle due implemenmtazioni.

Quindi devo mettere quanto tempo ci impiega a calcolare i termini la funzione ricorsiva e quanto quella iterativa. Come posso fare? so che devo usare la libreria time.h ma nn so i comandi.

Grazie :D

Il codice ora è: (dovrebbe essere abbastanza giusto)
Codice sorgente - presumibilmente C

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <time.h>
  4.  
  5. int calcolo(double epsilon);
  6. int fibonacci_iterativo(int val);
  7. int fibonacci_ricorsivo(int val);
  8.  
  9. int main()
  10. {
  11.    
  12.     double epsilon;
  13.     int val, risp;
  14.    
  15.     printf("Con quale epsilon vuoi lavorare?\n epsilon 1= 1.E-5 \n epsilon 2= 1.E-12 \nInserisci il valore(1 o 2): ");
  16.     scanf("%d", &risp);
  17.     if (risp < 1 || risp > 2)
  18.      printf("\nHai inserito un valore di epsilon non valido\n");
  19.     else
  20.      if (risp == 1)
  21.      {
  22.       epsilon = 1.E-5;
  23.       calcolo_iter(epsilon);
  24.       calcolo_ricor(epsilon);
  25.      }
  26.      else
  27.       {
  28.        epsilon = 1.E-12;
  29.        calcolo_iter(epsilon);
  30.        calcolo_ricor(epsilon);
  31.       }
  32. }
  33.  
  34. /* Funzione Calcolo Valori con Fibonacci Iterativo */
  35. int calcolo_iter(double epsilon)
  36. {
  37.        int i, count = 0, val;
  38.        double a,b,c,g,h;
  39.      
  40.        printf("\nCalcolo con Funzione Iterativa\n\n");
  41.        g = (sqrt(5.0) - 1 )/2;
  42.        i=1;
  43.        a = fibonacci_iterativo(i);
  44.        b = fibonacci_iterativo(i-1);
  45.        c = ((b)/a);
  46.        /*h = fabs(c-g);
  47.        printf ("c-g vale: %.12lf \n", h);*/ /*Operazione in più solo per verificare che valore assume h*/
  48.        while ((fabs(c-g)) > epsilon )
  49.        {
  50.         count = count + 1;
  51.         i=i+1;
  52.         a = fibonacci_iterativo(i);
  53.         b = fibonacci_iterativo(i-1);
  54.         c = ((b)/a);
  55.         /*h = fabs(c-g);
  56.         printf("C: %.12lf \n", c);
  57.         printf("G: %.12lf \n", g);
  58.         printf ("c-g vale: %.12lf \n", h);*/ /*Controllo per h*/
  59.        }
  60.        printf("Sono neccessari %d termini.\n", count);    
  61. }
  62.  
  63. /*Funzione Iterativa Fibonacci*/
  64.  
  65. int fibonacci_iterativo(int val)
  66.  {
  67.   int d, e, f;
  68.  
  69.   d=0;
  70.   e=1;
  71.  
  72.   while (val > 0)
  73.   {
  74.     f = d + e;
  75.     d = e;
  76.     e = f;
  77.     val = val-1;
  78.   }
  79.  
  80.   return (d);
  81.  }
  82.  
  83. /* Funzione Calcolo Valori con Fibonacci Ricorsivo */
  84. int calcolo_ricor(double epsilon)
  85. {
  86.        int i, count = 0, val;
  87.        double a,b,c,g,h;
  88.        
  89.        printf("\nCalcolo con Funzione Ricorsiva\n\n");
  90.        g = (sqrt(5.0) - 1 )/2;
  91.        i=1;
  92.        a = fibonacci_ricorsivo(i);
  93.        b = fibonacci_ricorsivo(i-1);
  94.        c = ((b)/a);
  95.        /*h = fabs(c-g);
  96.        printf ("c-g vale: %.12lf \n", h);*/ /*Operazione in più solo per verificare che valore assume h*/
  97.        while ((fabs(c-g)) > epsilon )
  98.        {
  99.         count = count + 1;
  100.         i=i+1;
  101.         a = fibonacci_ricorsivo(i);
  102.         b = fibonacci_ricorsivo(i-1);
  103.         c = ((b)/a);
  104.         /*h = fabs(c-g);
  105.         printf("C: %.12lf \n", c);
  106.         printf("G: %.12lf \n", g);
  107.         printf ("c-g vale: %.12lf \n", h);*/ /*Controllo per h*/
  108.        }
  109.        printf("Sono neccessari %d termini.\n", count);    
  110. }
  111. /*Funzione Ricorsiva Fibonacci*/
  112.  
  113. int fibonacci_ricorsivo (int val)
  114. {
  115.   if (val==0)    
  116.    return (0);
  117.   else
  118.   {
  119.    if (val==1)
  120.     return (1);
  121.    else
  122.       return (fibonacci_ricorsivo(val-1) + fibonacci_ricorsivo(val-2));
  123.   }
  124. }


Ultima modifica effettuata da FireAxe il 15/02/2008 alle 13:57
PM Quote
Avatar
bangirasu (Normal User)
Rookie


Messaggi: 39
Iscritto: 15/08/2007

Segnala al moderatore
Postato alle 15:31
Venerdì, 15/02/2008
Il problema della differenza di count e i è perchè count va inizializzato a 1 (come avevo già scritto).

Per calcolare il tempo di esecuzione puoi usare una cosa del genere:

Codice sorgente - presumibilmente C++

  1. #include <time.h>
  2. #include <stdio.h>
  3.  
  4. int main() {
  5.   clock_t Start;
  6.   clock_t Stop;
  7.  
  8.   ... varie inizializzazioni ...
  9.  
  10.   Start=clock();
  11.  
  12.   ... codice da cronometrare ...
  13.  
  14.  
  15.   Stop=clock();
  16.   printf("Secondi trascorsi: %3.5f\n", ((double)(Stop-Start))/CLOCKS_PER_SEC);
  17.   return 0;
  18. }



Il casting a double serve perchè tutte le variabili dell'espressione sono degli int (o long int nel caso dei clock_t) quindi se non ci fosse un casting il risultato dell'espressione sarebbe un int.

PM Quote
Avatar
FHF93 (Ex-Member)
Pro


Messaggi: 132
Iscritto: 13/11/2007

Segnala al moderatore
Postato alle 18:40
Venerdì, 15/02/2008
Potresti usare l'Api GetTickCount che è ancora più semplice ...
Ora te la improvviso se non ricordo male dovrebbe essere così:

Codice sorgente - presumibilmente C/C++

  1. #include <windows.h>
  2. ...
  3. ...
  4. int Start;
  5. Start=GetTickCount();
  6. /*Codice*/
  7. printf("Impiegato %d ms",(GetTickCount() - Start));



Fabrizio
Dio disse : "chi odia la scuola scagli la prima pietra" ... E così nacquero le montagne...
PM Quote
Avatar
FireAxe (Normal User)
Newbie


Messaggi: 5
Iscritto: 14/02/2008

Segnala al moderatore
Postato alle 11:20
Sabato, 16/02/2008
Testo quotato

Postato originariamente da bangirasu:

Il problema della differenza di count e i è perchè count va inizializzato a 1 (come avevo già scritto).

Per calcolare il tempo di esecuzione puoi usare una cosa del genere:

Codice sorgente - presumibilmente C++

  1. #include <time.h>
  2. #include <stdio.h>
  3.  
  4. int main() {
  5.   clock_t Start;
  6.   clock_t Stop;
  7.  
  8.   ... varie inizializzazioni ...
  9.  
  10.   Start=clock();
  11.  
  12.   ... codice da cronometrare ...
  13.  
  14.  
  15.   Stop=clock();
  16.   printf("Secondi trascorsi: %3.5f\n", ((double)(Stop-Start))/CLOCKS_PER_SEC);
  17.   return 0;
  18. }



Il casting a double serve perchè tutte le variabili dell'espressione sono degli int (o long int nel caso dei clock_t) quindi se non ci fosse un casting il risultato dell'espressione sarebbe un int.



Se io vorrei avere il tempo in centesimi invece che in secondi? perchè l'operazione rischia di essere più veloce di 1 secondo e quindi darmi 0,0000

PM Quote
Avatar
FireAxe (Normal User)
Newbie


Messaggi: 5
Iscritto: 14/02/2008

Segnala al moderatore
Postato alle 11:50
Sabato, 16/02/2008
ops scusate, doppio post

Ultima modifica effettuata da FireAxe il 16/02/2008 alle 11:51
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo