¿Cuál es la complejidad temporal del algoritmo de Euclides (límite superior, límite inferior y promedio)?

Lo busqué en línea en muchos sitios, pero ninguno da una respuesta clara . Todos ellos dan una gran cantidad de cosas matemáticas complicadas que no solo son difíciles de comprender para mí, sino que también son irrelevantes, ya que simplemente quiero saber cuál es el límite superior (complejidad en el peor de los casos), el límite inferior y la complejidad de tiempo promedio del algoritmo de Euclides. Esto es lo que he recopilado de una gran cantidad de sitios, ninguno dice lo mismo:

Encontrar mcd ( a , b ) , con b < a , y b teniendo número de dígitos h :

  • Algunos dicen que la complejidad del tiempo es O ( h 2 )

  • Algunos dicen que la complejidad del tiempo es O ( registro a + registro b ) (asumiendo registro 2 )

  • Otros dicen que la complejidad del tiempo es O ( registro a registro b )

  • Uno incluso dice esto "Por el teorema de Lame encuentras un primer número de Fibonacci mayor que b. Si es F [ k + 1 ] hay menos de k llamadas recursivas. Así es O ( registro b ) "

  • Todos dicen que el peor de los casos es cuando a y b son números de Fibonacci consecutivos.

Estaría muy agradecido si resuelve todo el asunto de manera concluyente dándome respuestas directas y claras a lo siguiente:

  1. ¿Cuál es la complejidad temporal del peor de los casos (límite superior) del algoritmo de Euclides?

  2. ¿Cuál es la complejidad de tiempo de caso promedio del algoritmo de Euclides?

  3. ¿Cuál es el límite inferior del Algoritmo de Euclides (mejor de los casos) y cuándo sucede?

No tienes idea de cuánto me ayudará tu respuesta. Estoy muy abatido porque estoy empantanado por lo que puede considerarse un algoritmo bastante simple. Gracias.

¿A qué te refieres con promedio? Quieres decir a , b aleatorio por debajo de algún límite norte , a fijo y b abajo a 1 o algo diferente? Esto no está claro en el contexto y no hay una definición estándar. Creo que el mejor de los casos es a o b igual a 0 .
Bueno, utilicé el término "Caso promedio", ya que generalmente se usa para algoritmos como ordenar, buscar... Ya sabes... Sería igualmente amable de tu parte si me pudieras contar en pocas palabras sobre cada uno de esos 2 casos que mencionaste. De lo contrario, deja el "caso promedio" y, por favor, cuéntame solo sobre el límite superior y el límite inferior. del día.
@Ivy: Hans hizo una pregunta muy precisa y señaló correctamente que no existe una definición estándar, por lo que no es útil referirse a él sobre cómo el término "se usa generalmente". En los ejemplos que citó (clasificación, búsqueda), generalmente hay una interpretación obvia y bien definida de "promedio", a saber, que los elementos que se ordenarán/insertarán/buscarán aparecen en un orden uniformemente elegido al azar de todas las permutaciones posibles. No hay una interpretación tan obvia aquí.
Mi falta de conocimiento me impide responder a esta pregunta. Pero sé que el análisis de complejidad es un tema delicado en el que hay que tener mucho cuidado al hacer y responder preguntas.
Si un tipo como tú dice "Mi falta de conocimiento...", ¡entonces me pregunto dónde se encuentra un tipo como yo! LOL. Estoy seguro de que ni siquiera sé una fracción de lo que sabes sobre estas cosas. Bueno, me alegro de que haya dicho que "el análisis de la complejidad es un tema delicado". Me ayuda a sentirme mejor mientras lucho y me retraso en este tema. todos. Pero por qué molestarse, con foros como estos, nadie está solo... ¡las personas inteligentes están ahí para ayudar a los luchadores como yo!
Para ampliar la información aquí, un gran recurso es ... en.wikipedia.org/wiki/…
Para futuros lectores: el mejor recurso que he visto sobre esto se encuentra en el Volumen 2 de la AOCP de Knuth (Capítulo 4.5.1-4.5.3).
Hay un artículo de Jonassen y Knuth, "A Trivial Algorithm cuyo análisis no lo es" , Journal of Computer and System Sciences 16:3 (junio de 1978), págs. 301–322. No seas demasiado duro contigo mismo.

Respuestas (2)

Para abordar algunos preliminares, dejemos T ( a , b ) Sea el número de pasos tomados en el algoritmo euclidiano, que evalúa repetidamente mcd ( a , b ) = mcd ( b , a modificación b ) hasta b = 0 , asumiendo a b . También, deja h = registro 10 b Sea el número de dígitos en b (Da o toma). (Tenga en cuenta que en estos cálculos, al contar los pasos, ignoramos la cuestión de la complejidad temporal de la metro o d función. Si suponemos que es O ( 1 ) , entonces todo lo siguiente también se aplica a la complejidad temporal del algoritmo.

  1. En el peor de los casos, como usted ha dicho, a = F norte + 1 y b = F norte , dónde F norte es la sucesión de Fibonacci, ya que calculará mcd ( F norte + 1 , F norte ) = mcd ( F norte , F norte 1 ) hasta que llega a norte = 0 , entonces T ( F norte + 1 , F norte ) = Θ ( norte ) y T ( a , F norte ) = O ( norte ) . Desde F norte = Θ ( φ norte ) , esto implica que T ( a , b ) = O ( registro φ b ) . Tenga en cuenta que h yo o gramo 10 b y registro b X = registro X registro b implica registro b X = O ( registro X ) para cualquier a , por lo que el peor de los casos para el algoritmo de Euclides es O ( registro φ b ) = O ( h ) = O ( registro b ) .

  2. El caso promedio requiere un poco más de cuidado, ya que depende de las probabilidades de la situación. Para calcularlo con precisión, necesitamos una distribución de probabilidad. Si a es fijo y b se elige uniformemente de Z [ 0 , a ) , entonces el número de pasos T ( a ) es

    T ( a ) = 1 2 + 6 registro 2 π ( 4 γ 24 π 2 ζ ( 2 ) + 3 registro 2 2 ) + 12 π 2 registro 2 registro a + O ( a 1 / 6 + ϵ ) ,

    o, para menor precisión, T ( a ) = 12 π 2 registro 2 registro a + O ( 1 ) . (Fuente: Wikipedia)

  3. En el mejor de los casos, a = b o b = 0 o sucede algún otro caso conveniente como ese, por lo que el algoritmo termina en un solo paso. De este modo, T ( a , a ) = O ( 1 ) .

Si estamos trabajando en una computadora con cálculos de 32 bits o de 64 bits, como es común, entonces el individuo modificación las operaciones son, de hecho, de tiempo constante, por lo que estos límites son correctos. Sin embargo, si estamos haciendo cálculos de precisión arbitraria, entonces para estimar la complejidad de tiempo real del algoritmo, necesitamos usar eso modificación tiene complejidad de tiempo O ( registro a registro b ) . En este caso, todo el "trabajo" se realiza en el primer paso, y el resto del cálculo también se realiza O ( registro a registro b ) , entonces el total es O ( registro a registro b ) . Sin embargo, quiero enfatizar que esto solo se aplica si el número es tan grande que necesita precisión arbitraria para calcularlo.

(Esto subraya la diferencia entre la notación O grande del matemático y la O grande del programador: en el primer caso, desea que el límite sea verdadero norte , incluso esos norte que son tan absurdamente grandes que nadie puede escribirlos o almacenarlos en la memoria, mientras que en el segundo caso, los programadores están interesados ​​principalmente en norte [ 0 , 2 64 ] , y esa es una estimación generosa. Para ellos, es más importante ver la "contribución principal" a la complejidad del tiempo, y para el algoritmo euclidiano, el número más pequeño impulsa la dificultad del cálculo en general).

¿Estás contando pasos? Creo que está pidiendo complejidad "general", sea lo que sea que esto signifique.
Gracias Gracias Gracias Mario!! Has respondido lo que quería saber, en un formato numerado. Pero solo tengo una pequeña confusión con tu respuesta. En 1), dices que Fn es la secuencia de Fibonacci y luego dices Fn=Θ (φn). ¿Cómo se puede equiparar una secuencia a una Complejidad? ¿Quiere decir que alguna operación particular en la Secuencia de Fibonacci es Θ(φn). En caso afirmativo, ¿a qué operación se refiere, es decir, Θ(φn)? Por favor aclare eso. mi formateo... si es posible, dame un enlace donde pueda aprender el código de marcado para formatear preguntas/respuestas en este foro. No sé nada al respecto)
Él estima el tamaño de F norte con φ norte .
Oh, gracias Hans. Por cierto, ¿qué estabas pensando acerca de la complejidad "general"? ¿Qué quieres decir exactamente con eso? En el contexto del Algoritmo de Euclides, generalmente nos referimos al número de pasos, ¿no?
Quiero decir, ¿qué tan caro es un paso? El número de pasos sólo depende de b . Pero la complejidad general debe implicar a ya que tienes que hacer algo con a . Si permite arbitrariamente grandes a y b no tomas la operación mod como constante. Por lo tanto, obtendrá una complejidad general que involucra registro a y registro b . Pero no me malinterpretes. Creo que la respuesta de Mario es soberbia.
Bueno, Hans, por favor, elabore con una respuesta completa porque ahora estoy realmente confundido. Algunos sitios han dado la complejidad en términos de a y b. Algunos dicen O (loga.logb) mientras que otros dicen O (loga + logb) .¿Cuál es la correcta? Esperemos que Mario diga algo al respecto. Además, ¿puede explicar por qué "para a y b arbitrariamente grandes no toma la operación de mod como constante". Repito, explique por qué. Y Hans , en cuanto al costo de un paso, wikipedia dice que es igual a h, el número de dígitos en b, el número más pequeño. De ahí el límite superior O (h ^ 2) ... según wikipedia.
La definición matemática de la notación O grande es en términos de la tasa de crecimiento de las funciones, no del tiempo real necesario para realizar las operaciones. Cuando yo digo F norte = Ω ( φ norte ) , Quiero decir que F norte A φ norte para algunos A , y lo suficientemente grande norte . @HansGiebenrath, es cierto que ignoro la complejidad temporal del mod y lo digo al principio. Si no lo hace, y a b , entonces dado que la operación mod depende de cada dígito en a en el peor de los casos, obtienes O ( registro a ) para el primer paso y O ( 1 ) para los demás, por lo que obtienes O ( registro a + registro b ) , pero la constante es mucho menor en el a .
Mario, ¿entonces debo concluir que todos esos sitios que dicen cosas como O(loga.logb) son absurdos? ¿Es algo como O(loga.logb) totalmente absurdo en este contexto? mod aquí, ¿debería recalcar en mi mente para mi examen que si se consideran tanto el número de pasos como la complejidad del tiempo de la operación del mod (cada paso), entonces la complejidad es O (loga+logb)? ¿Esta edición tuya será más apropiado que el O (logb) en "1)" si también tomamos en cuenta la complejidad del tiempo de la modificación. Por favor, responda esto, amigo.
Lo siento, mi error, tienes que dividir a con b en ese primer paso, por lo que la contribución es en realidad O ( registro a registro b ) y obtienes O ( registro a registro b ) , no O ( registro a + registro b ) para el cálculo completo. En resumen, la complejidad del tiempo es O ( registro a registro b ) con mod tenido en cuenta y O ( registro b ) si estás contando pasos.
Gracias por aclarar todo Mario. Me alegro de haberme unido a este foro de Matemáticas a pesar de la aprensión inicial de que se burlarían de mis preguntas rudimentarias y quedarían sin respuesta... Espera, espera, espera... Otra vez me perdí algo. ¿Cuál es el primer paso? ¿Quieres decir cuando dijiste "Tienes que dividir a con b en ese primer paso"? Por favor, menciónalo para mí, ya que no quiero aprender esta fórmula de memoria después de todo este análisis. ¿Cómo obtenemos O (logalogb) de O(loga +logb)?
Lo que quiero decir Mario es esto: Dividir a por b en O(loga+logb) ¿no obtendríamos O(loga-logb+logb) u O(loga)? ¿Cómo obtenemos O(logalogb)?
Gracias por el esfuerzo Mario. @IvyMike: en cada paso, divide números que están delimitados por a . Por lo tanto, cada división está en O ( registro a ) . Puesto que hay O ( registro b ) divisiones, tenemos O ( registro a registro b ) .
@HansGiebenrath En realidad, la complejidad temporal de la división o el módulo es O ( registro a registro b ) (o O ( registro 2 a ) desde a b ) por lo que la estimación ingenua es en realidad O ( registro a registro 2 b ) . Hay una razón un poco complicada que tiene que ver con la velocidad a la que los números están disminuyendo, lo que explica por qué la complejidad del tiempo total es O ( registro a registro b ) sobre todos los pasos. Consulte la página 94 de shoup.net/ntb/ntb-v2.pdf para ver la prueba.
@MarioCarneiro Mi error. Por supuesto que tienes razón. Siempre pienso en términos de "suave"-O, ignorando todos los factores logarítmicos. Entonces usar el algoritmo de la división de Schönhage-Strassen es solo O ~ ( registro a ) . Y también gracias por la referencia. Este libro se ve muy bien.

el tiempo de ejecución es lineal en la representación de números más grandes: si a b entonces el tiempo de ejecución es O ( registro ( a ) )

Suponiendo que la operación mod y div se puede realizar en O (1), si mod y div se pueden realizar en O (log (a)) el tiempo de ejecución del algoritmo es O (log ^ 2 (a))