Soluzioni: Lezione 6

../_images/linea.png

6.1 implementazione dell’algoritmo della bisezione

  • esercizio01.cpp

/*
Esercizio 11: Si determini con il metodo della bisezione lo zero della funzione g(x) = cos(x) nell'intervallo (0, 4).
Quali controlli sono stati omessi, nell'implementazione dell'algoritmo descritta nel testo della lezione, che potrebbero accelerare il risultato?

c++ -o esercizio11 esercizio11.cpp
*/

#include <iostream>
#include <cmath>


double fcos (double x) 
  {
    return cos (x) ; 
  }


double bisezione ( double g (double), double xMin, double xMax, double precision)
{
  double xAve = xMin ;
  while ((xMax - xMin) > precision)
    {
      xAve = 0.5 * (xMax + xMin) ;
      if (g (xAve) * g (xMin) > 0.) xMin = xAve ;
      else                          xMax = xAve ;
    }
  return xAve ;
}  

//----------------- MAIN -----------------
int main (int argc, char ** argv)
{
  double x_min = 0.;
  double x_max = 4.;
  double risoluzione = 0.0001;

  std::cout << "Zero della funzione = " << bisezione (fcos, x_min, x_max, risoluzione) << std::endl ;
  return 0 ;
}
../_images/linea.png

6.2 implementazione dell’algoritmo della bisezione in modo ricorsivo

  • esercizio02.cpp

/*
Esercizio 12: Si svolga l'esercizio precedente utilizzando una funzione ricorsiva.

c++ -o esercizio12 esercizio12.cpp
*/

#include <iostream>
#include <cmath>


double fcos (double x) 
  {
    return cos (x) ; 
  }


double bisezione_ricorsiva ( double g (double), double xMin, double xMax, double precision)
{   
  double xAve = 0.5 * (xMax + xMin) ;
  if ((xMax - xMin) < precision) return xAve ;
  if (g (xAve) * g (xMin) > 0.) return bisezione_ricorsiva (g, xAve, xMax, precision) ;
  else                          return bisezione_ricorsiva (g, xMin, xAve, precision) ;
}  

//----------------- MAIN -----------------
int main (int argc, char ** argv)
{
  double x_min = 0.;
  double x_max = 4.;
  double risoluzione = 0.0001;

  std::cout << "Zero della funzione = " << bisezione_ricorsiva (fcos, x_min, x_max, risoluzione) << std::endl ;
  return 0 ;
}
../_images/linea.png

6.3 calcolo ricorsivo del fattoriale di un numero

  • esercizio03.cpp

/*
Esercizio 13: Si implementi una funzione che calcola il fattoriale di un numero utilizzando una funzione ricorsiva.

c++ -o esercizio13 esercizio13.cpp
*/

#include <iostream>
#include <cmath>

int fattoriale (int n)
{
  if (n == 0) return 1;
  return (n * fattoriale(n-1));
}

//----------------- MAIN -----------------
int main()
{
  int num = 6;
    
  if (num < 0)
    {
      std::cout << "Numero negativo,il fattoriale non è definito" << std::endl;
      return -1;
    }
  
  std::cout << "Il fattoriale  e`: " << fattoriale (num) << std::endl;
  
  return 0;

}
../_images/linea.png

6.4 determinazione del minimo di una funzione con il metodo della sezione aurea

  • esercizio04.cpp

/*
Esercizio 14: Si determini con il metodo della sezione aurea il minimo della funzione g(x) = x2 + 7.3x + 4 nell'intervallo (-10, 10).

c++ -o esercizio14 esercizio14.cpp
*/

#include <iostream>
#include <cmath>


double funz (double x)
{
  return (x*x + 7.3*x + 4);

} 

double sezioneAurea (double g (double),double x0, double x1, double precision)
{
  double r = 0.618;
  double x2 = 0;
  double x3 = 0; 
  double larghezza = fabs(x1-x0);
   
  while (larghezza > precision)
    {        
        x2 = x0 + r * (x1 - x0) ;
        x3 = x0 + (1. - r) * (x1 - x0);  
    
      if (g(x3) > g(x2) ) 
       {  //restringo l'intervallo tennedo fisso uno dei due estremi e spostando l'altro        
          x0 = x3;
          x1 = x1;         
        }            
      else 
          { //restringo l'intervallo tennedo fisso uno dei due estremi e spopstando l'altro
             x1 = x2;
             x0 = x0;          
          }
          
        larghezza = fabs(x1-x0) ;            
    } 
                                 
  return (x0+x1)/2. ;
}

//----------------- MAIN -----------------
int main (int argc, char ** argv)
{
  double x_min = - 10.;
  double x_max = 10.;
  double risoluzione = 0.0001;
  
  std::cout << "Minimo della funzione " << sezioneAurea (funz, x_min, x_max, risoluzione) << std::endl;
  
 return 0;
 } 
../_images/linea.png

6.5 implementazione ricorsiva del metodo della sezione aurea

  • esercizio05.cpp

/*
Esercizio 15: Si svolga l'esercizio precedente utilizzando una funzione ricorsiva.

c++ -o esercizio15 esercizio15.cpp
*/

#include <iostream>
#include <cmath>


double funz (double x)
{
  return (x*x + 7.3*x + 4);

} 

double sezioneAurea_ricorsiva (double g (double),double x0, double x1, double precision)
{
  double r = 0.618;
  double x2 = x0 + r * (x1 - x0) ;
  double x3 = x0 + (1. - r) * (x1 - x0); 
  double larghezza = fabs(x1-x0);
  
  if (larghezza < precision)   return (x0+x1)/2. ;    
  if (g (x3) > g (x2) )  return sezioneAurea_ricorsiva(g,x3,x1,precision);
  else                   return sezioneAurea_ricorsiva(g,x0,x2,precision);   
}

//----------------- MAIN -----------------
int main (int argc, char ** argv)
{
  double x_min = - 10.;
  double x_max = 10.;
  double risoluzione = 0.0001;
  
  std::cout << "Minimo della funzione " << sezioneAurea_ricorsiva (funz, x_min, x_max, risoluzione) << std::endl;
  
 return 0;
 } 
../_images/linea.png

6.6 determinazione del massimo di una funzione con il metodo della sezione aurea

  • esercizio06.cpp

/*
Esercizio 16: Si svolgano i due esercizi precedenti cercando il massimo di una funzione a scelta.

c++ -o esercizio16 esercizio16.cpp
*/

#include <iostream>
#include <cmath>


double fsin (double x)
{
  return sin(2*x);

} 

double sezioneAurea_max (double g (double),double x0, double x1, double precision)
{
  double r = 0.618;
  double x2 = 0;
  double x3 = 0; 
  double larghezza = fabs(x1-x0);
   
  while (larghezza > precision)
    {        
        x2 = x0 + r * (x1 - x0) ;
        x3 = x0 + (1. - r) * (x1 - x0);  
    
      if (g(x3) < g(x2) ) 
       {  //restringo l'intervallo tennedo fisso uno dei due estremi e spostando l'altro        
          x0 = x3;
          x1 = x1;         
        }            
      else 
          { //restringo l'intervallo tennedo fisso uno dei due estremi e spopstando l'altro
             x1 = x2;
             x0 = x0;          
          }
          
        larghezza = fabs(x1-x0) ;            
    } 
                                 
  return (x0+x1)/2. ;
}


double sezioneAurea_max_ricorsiva (double g (double),double x0, double x1, double precision)
{
  double r = 0.618;
  double x2 = x0 + r * (x1 - x0) ;
  double x3 = x0 + (1. - r) * (x1 - x0); 
  double larghezza = fabs(x1-x0);
  
  if (larghezza < precision)   return (x0+x1)/2. ;    
  if (g(x3) < g(x2) )          return sezioneAurea_max_ricorsiva(g,x3,x1,precision);
  else                         return sezioneAurea_max_ricorsiva(g,x0,x2,precision); 
}


//----------------- MAIN -----------------
int main (int argc, char ** argv)
{
  double x_min = 0.;
  double x_max = 2*M_PI;  
  double risoluzione = 0.0001;
  
  std::cout << "Massimo della funzione " << sezioneAurea_max (fsin, x_min, x_max, risoluzione) << std::endl;
  std::cout << "Massimo della funzione usando la funzione ricorsiva " << sezioneAurea_max_ricorsiva (fsin, x_min, x_max, risoluzione) << std::endl;
  
 return 0;
 } 
../_images/linea.png