Foros del Web » Programación para mayores de 30 ;) » C/C++ »

ideas para mejorar velocidad de código nofibonacci.

Estas en el tema de ideas para mejorar velocidad de código nofibonacci. en el foro de C/C++ en Foros del Web. Bueno, primeramente hola y no vengo a que me hagan la tarea , mas bien vengo a que me ayuden a mejorar el tiempo de ...
  #1 (permalink)  
Antiguo 28/07/2011, 11:48
 
Fecha de Ingreso: julio-2011
Ubicación: Querétaro México
Mensajes: 34
Antigüedad: 13 años, 5 meses
Puntos: 0
Pregunta ideas para mejorar velocidad de código nofibonacci.

Bueno, primeramente hola y no vengo a que me hagan la tarea , mas bien vengo a que me ayuden a mejorar el tiempo de ejecución de este programa que hice o bien si se les ocurre un algoritmo mejor pues sería bien recibido, pero explicado por que quiero aprender : ).

El programa tiene que resolver el mayor de los casos en tiempo <= 1 segundo y el mio tarda como 7.
aqui el problema en una imagen:


otro ejemplo de entrada: 13
otro ejemplo salida:4 6 7 9 10 11 12

¿Cómo podría hacerlo mas rápido, hasta tiempo <=1 segundo ? D:

Cita:
#include <cstdlib>
#include <iostream>

using namespace std;



int vector[300000];
int main()
{

int numero,j,i,N;

cin>>N;

vector[0]=1;
vector[1]=2;
i=1;
while(numero<N)
{ i++;
vector[i]=vector[i-2]+vector[i-1];

numero=vector[i-1];
while(numero<vector[i]){
numero++;
if(numero!=3&&numero!=vector[i-1]&&numero!=vector[i]&&numero<N)
cout<<numero<<" ";
}
}
return 0;
}
mi algoritmo es simple, creo un numero fibonacci, me regreso al anterior numero fibonacci y cuento a la vez que imprimio hasta llegar al numero fibonacci que cree, y así sucesivamente D:, pero es muy tardado .

¿alguna idea?, no precisamente en código pero ideas...
Saludos : ).
  #2 (permalink)  
Antiguo 28/07/2011, 13:27
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 22 años, 1 mes
Puntos: 52
Respuesta: ideas para mejorar velocidad de código nofibonacci.

Bueno. No fue tan complicado :).

Para poder lograr construir un algoritmo mas eficiente hay que saber un poco de analisis de algoritmos. Aunque sea lo mas basico.

En este caso tu algoritmo es bonito.
Pero el cuello de botella es que tienes ciclos anidados.
Una de las primeras cosas que hay que intentar cambiar para hacer un algoritmo mas eficiente es quitar en lo mas que se pueda los ciclos anidados.

Despues de de analizar un poco el programa logre obtener una solucion donde solo se utiliza un ciclo.

Código:
#include <cstdlib>
#include <iostream>

using namespace std;



int vector[300000];
int main()
{
	int numero,j,i,N;
	numero=0;
	i=0;
	j=2;
	
	
	cin>>N;
	vector[0]=1;
	vector[1]=2;
	for(i=3; i<N; i++)
	{
		if(i==vector[j-2]+vector[j-1])
		{
			vector[j]=i;
			j++;
		}
		else
			cout<<i<<" ";
	}
	return 0;
}
Si vez el codigo es mas sencillo aun.

El chiste es ir imprimiendo tooodos los numeros menos los de la serie de fibonacci.
Entonces solo necesitamos revisar que el numero que vamos a imprimir no sea de la serie, y si lo es, pues lo almacenamos para asi tener el siguiente valor de la serie y estarlo probando.
Pruebalo, seguramente correra en un factor lineal en vez de cuadratico, lo cual acelera muuucho a la hora de probar casos de incluso mas de 30000.

Podria pensar en otro tipo de algoritmos para intentar acelerarlo mas, pero ya seria un incremento insignificante en velocidad y gran incremento en complejidad, por lo que no valdria la pena.

Espero te sea de ayuda.

SAludos
  #3 (permalink)  
Antiguo 28/07/2011, 15:58
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años, 8 meses
Puntos: 228
Respuesta: ideas para mejorar velocidad de código nofibonacci.

Igualmente si analisas el otro codigo no es cuadratico por mas que tenga dos while anidados. Fijate que la variable numero aumenta en uno por uno al igual que lo esta haciendo en el tuyo. Y no vuelve a empezar a contar cuando sale del while interno.

Ademas si te fijas tarda casi lo mismo que el otro codigo. Yo creo que la gran diferencia de tiempo se esta perdiendo en el hecho de escribir en pantalla.

Si te fijas bien con cualqioera de los dos codigos si escribimos en un archivo redirigiendo el stdout el algoritmo corre en menos de unsegudno.
Ejecutucando de esta forma:
miprog.exe > salida.txt

o en linux
./miprog > salida.txt

Saludos

Es mas se podria tener ya precargado la serie de fibonacci.

Código C:
Ver original
  1. for (i = 4 ; i < N ; i++)
  2.   if ( (i != 3 && i != 5 && i != 8 && i != 13 && i != 21 && i != 34 && i != 55 && i != 89 && i != 144 )  && (i != 233 &&  i != 377 && i != 610 && i !=987 && i !=1597 && i !=2584 && i !=4181 && i !=6765 && i !=10946 &&  i != 17711 && i != 28657 && i != 46368 && i != 75025 && i != 121393 && i != 196418 && i != 317811 ))
  3.       cout << i << " ";
  #4 (permalink)  
Antiguo 28/07/2011, 16:42
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 22 años, 1 mes
Puntos: 52
Respuesta: ideas para mejorar velocidad de código nofibonacci.

Tienes razón. El segundo while no implica un factor cuadrático.
De hecho despues de analizar un poco mas, he visto que el mismo compilador(en linux gcc), al hacer las optimizaciones necesarias queda casi de la misma manera.
Es poca la diferencia.

Sin embargo podria defender un poco el codigo que puse ya que al hacer un menor numero de comparaciones (if's.) y la simplicidad del codigo en si ayudan en poca medida a la eficiencia.

Ahora, si lo que tarda mas es imprimir en pantalla( en mi maquina es instantaneo hasta con el número 100,000). Seria bueno ver si lo mas pesado es el mismo cout, o el conjunto de llamadas al sistema para imprimir en pantalla.
Seria bueno saberlo.
Aun asi. Buen experimento jajaja.

Saludos
  #5 (permalink)  
Antiguo 28/07/2011, 19:34
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años, 8 meses
Puntos: 228
Respuesta: ideas para mejorar velocidad de código nofibonacci.

YO lo probe con 300.000 y ahi tarde unos cuantos segundos. Desde que empece a programar siempre aprecia que en los ciclos esos cuanto menos informacion detallaba mas rapida iba la cuentios.

Desde Qbasic que notaba esa letencia si imprimia en pantalla mientras calculaba cosas. Asi que creo que debe ser el problema de las llamadas al sistema para imprimir en pantalla lo que lo deben demorar.

Saludos
  #6 (permalink)  
Antiguo 11/08/2011, 13:03
 
Fecha de Ingreso: agosto-2011
Mensajes: 4
Antigüedad: 13 años, 4 meses
Puntos: 0
Respuesta: ideas para mejorar velocidad de código nofibonacci.

aqui les pongo mi solucion en la que creo que se hacen menos comparaciones y para ver bien el tiempo real sin las impreciones solo es cosa de omitirlas y asignar a una variable el contador i cuando hay una imprecion

Código C++:
Ver original
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7.     int num1 = 1, num2 = 1, n;
  8.    
  9.     cout << "Ingrese N: ";
  10.     cin >> n;
  11.     for (int i = 1; i < n; ++i)
  12.     {
  13.         if (i < num2)
  14.             for(;i < num2 && i < n; ++i)
  15.                 cout << "i: " << i << "  ";
  16.         num2 += num1;
  17.         num1 = num2 - num1;
  18.     }
  19.     system("pause");
  20.     return 0;
  21. }
  #7 (permalink)  
Antiguo 11/08/2011, 14:24
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 10 meses
Puntos: 260
Sonrisa Respuesta: ideas para mejorar velocidad de código nofibonacci.

Hola,

Cita:
Iniciado por Instru Ver Mensaje
... Para poder lograr construir un algoritmo mas eficiente hay que saber un poco de analisis de algoritmos. Aunque sea lo mas basico. ...
... Una de las primeras cosas que hay que intentar cambiar para hacer un algoritmo mas eficiente es quitar en lo mas que se pueda los ciclos anidados. ...
Esos dos enunciados son posiblemente lo mejor que haya leido de programación en mucho tiempo.

Cita:
Iniciado por Instru Ver Mensaje
int vector[300000];
...
{
if(i==vector[j-2]+vector[j-1])
{
[/CODE]
Posiblemente no es necesario guardar toda la lista, simplemente los últimos dos valores, y en cada ciclo se hace una suma y dos restas por lo que se agrega un par de ciclos de procesador.

Cita:
Iniciado por sam90 Ver Mensaje
... Ademas si te fijas tarda casi lo mismo que el otro codigo. Yo creo que la gran diferencia de tiempo se esta perdiendo en el hecho de escribir en pantalla.
Definitivamente es cierto, un lenguaje más complejo siempre conlleva mas operaciones, cout hace muchas operaciones internamente, (comparado con el int 21 de assembler).

Cita:
Iniciado por sam90 Ver Mensaje
Código C:
Ver original
  1. for (i = 4 ; i < N ; i++)
  2.   if ( (i != 3 && i != 5 && i != 8 && i != 13 && i != 21 && i != 34 && i != 55 && i != 89 && i != 144 )  && (i != 233 &&  i != 377 && i != 610 && i !=987 && i !=1597 && i !=2584 && i !=4181 && i !=6765 && i !=10946 &&  i != 17711 && i != 28657 && i != 46368 && i != 75025 && i != 121393 && i != 196418 && i != 317811 ))
  3.       cout << i << " ";
Por cada ciclo se van a realizar tantas comparaciones que no creo que optimize mucho el código, cuando vaya por el 28657 se van a realizar mínimo 10 'not equals' por cada número, lo cual no creo que sea eficiente.

Cita:
Iniciado por sam90 Ver Mensaje
... Desde Qbasic que notaba esa letencia si imprimia en pantalla mientras calculaba cosas. Asi que creo que debe ser el problema de las llamadas al sistema para imprimir en pantalla lo que lo deben demorar. ...
Definitivamente un print de QBasic no ejecuta una interrupción de video simplemente, internamente realiza muchas operaciones.

Ahora bien ... no sé si yo no entendí algo .. pero realmente optimizado sería 'ALGO' así, a menos que yo no haya entendido el problema:

Código C:
Ver original
  1. int a = 1;
  2.     int b = 2;
  3.  
  4.     int i;
  5.     int p = a + b;
  6.  
  7.     for (i = p; i < 300; i++) {
  8.         if (i == p) {
  9.             a = b;
  10.             b = i;
  11.             p = a + b;
  12.         } else {
  13.             printf ("%d\n", i);
  14.         }
  15.     }

Se usa poca memoria y se cambian los valores solamente cuando es el siguiente de la serie, además no se suma ni resta en cada ciclo, solamente cuando encuentra un número de la secuencia, posiblemente me ahorro mucho con el printf, pero ya es cuestion de usar el cout, para obtener la misma velocidad de antes. Si las variables se almacenan en registros del procesador, el código va a ser sumamente rápido.

Saludos,

Etiquetas: c++, código, fibbonacci, algoritmos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:54.