Algoritmo para calcular el conjunto de soluciones de una sola ecuación simple con dos variables

Supongamos que tengo una ecuación simple de la forma:

7x + 4y = n

donde n es elegido por nosotros y x, y y n son todos números enteros positivos. Esta es la única ecuación que se nos da. Entre las posibles soluciones necesitamos la solución (x,y) en la que x es la más pequeña. p.ej

7x + 4y = 14, then (2, 0) is the solution
7x + 4y = 15, then (1, 2) is the solution
7x + 4y = 32, then (4, 1) and (0, 8) are the possible solutions,
of which (0, 8) is the correct solution

Me gustaría diseñar un algoritmo para calcularlo en el menor tiempo de ejecución posible. El algoritmo actual que tengo en mente es algo como esto:

Given an input n
Calculate max(x) = n/7
for i = 0 to max(x)
    If the equation 7*i + 4*y = n holds
        return value of i and y
    else
        continue

Este algoritmo, supongo, puede tener un tiempo de ejecución de hasta O(n) en el peor de los casos. ¿Hay algún algoritmo mejor para calcular la solución?

preguntado el 03 de mayo de 12 a las 14:05

Tu dices If the equation 7*i + 4*y = n holds Obtienes del bucle, pero ¿qué es y? -

¿Hay un límite superior en X e Y? Si es así, haz búsquedas binarias para alcanzar el éxito. -

Es posible que desee leer sobre programación entera lineal. Su problema es definitivamente una instancia específica del problema generalizado, pero tengo curiosidad por saber si existe una solución eficiente para el problema simplificado que enfrenta. -

Esto pide una solución para CodeChef mayo 2012 problema de concurso DIVPAIR :-(-

@Betlista he planteó el problema en meta si desea comentar más -

4 Respuestas

Consideremos el problema más general

  • Para dos enteros coprimos positivos a y b, dado un entero positivo n, encuentra la pareja (x,y) de enteros no negativos tales que a*x + b*y = n con mínimo x. (Si hay uno. No es necesario que lo haya, por ejemplo 7*x + 4*y = 5 no tiene solución con no negativo x y y.)

Ignorando la no negatividad por el momento, dada cualquier solución

a*x0 + b*y0 = n

todos los las soluciones tienen la forma (x0 - k*b, y0 + k*a) para algún entero k. Entonces el resto de x formulario b y de y formulario a es un invariante de las soluciones, y tenemos

a*x ≡ n (mod b), and b*y ≡ n (mod a)

entonces tenemos que resolver la ecuacion a*x ≡ n (mod b) - el otro sigue.

Asegúrate de que 0 < c ser un entero con a*c ≡ 1 (mod b). Lo encuentra, por ejemplo, mediante el algoritmo euclidiano extendido, o (equivalentemente) la expansión de fracción continua de a/b en O(log b) pasos. Ambos algoritmos producen naturalmente el único c < b con esa propiedad.

Entonces el candidato mínimo para x es el resto x0 of n*c formulario b.

El problema tiene solución con no negativa x y y si y solo si x0*a <= n, y entonces x0 es el mínimo no negativo x que aparece en cualquier solución con no negativo x y y.

Por supuesto, para los pequeños a y b como 7 y 4, la fuerza bruta no es más lenta que calcular el inverso de a formulario b.

contestado el 03 de mayo de 12 a las 15:05

Tenemos

7(x-4)+4(y+7)=7x+4y

Entonces, si (x, y) es una solución, entonces (x-4,y+7) también es una solución. Por lo tanto, si hay una solución, entonces hay una con x<4. Es por eso que solo necesita probar x = 0..3 que se ejecuta en tiempo constante.

Esto se puede extender a cualquier ecuación de la forma ax+by=n, solo necesita probar x=0..b-1.

contestado el 03 de mayo de 12 a las 15:05

Creo que la ecuación se puede cambiar. Lo que hay es solo una muestra. - tony ennis

Si la ecuación es de la forma ax+by=n entonces si hay una solución, entonces hay una con x < b. - Tomas

Su idea es buena y verdadera (creo), pero la respuesta no es lo suficientemente informativa. Si yo fuera usted, editaría la respuesta y agregaría más información y explicación. Si lo hace, es probable que algunos votantes negativos lo anulen. Le hice +1 de todos modos, por liderar el camino. - amit

Gracias por el consejo, lo haré. - Tomas

solución impresionante (y) - Archit Garg

Recomendaría revisar el método Simplex en el Recetas numéricas en C libro. Puede tratar fácilmente el código C como un pseudocódigo y crear una versión Java. La versión del simplex que desea es el "simplex restringido" que trata solo con valores positivos. El libro es disponible en línea gratis. Comience con la sección 10.8 y siga leyendo.

contestado el 03 de mayo de 12 a las 15:05

El método Simplex es increíble. - tony ennis

En) :

y=n/4;
while((n-4y)%7!=0 && y!=0){
 y--;
}
x=(n-4y)/7;

contestado el 03 de mayo de 12 a las 15:05

¿Por qué llamar piso en un número entero? Si n es un int, también lo es n/4. Además, por eficiencia, debe comenzar con x porque su límite superior es más pequeño. - Marko Topolnik

lo hice genérico... hay algunos lenguajes de programación que convierten divisiones en flotantes cuando el resultado no es un número entero. - Sebastián Breit

Así que decidió hacer que su código sea específico de Java en todos los aspectos, excepto en la llamada de piso. - Marko Topolnik

ok, me entendiste allí. No estaba seguro sobre el comportamiento de Java en este caso porque también solía desarrollar en otros idiomas. ¿Por qué estamos discutiendo eso en lugar del algoritmo? ¿Por qué no escribes una respuesta tú mismo en lugar de criticar el código de otras personas? - Sebastián Breit

Porque lo que escribiría está demasiado cerca de lo que ya tienes allí. Estoy tratando de motivarte para que lo limpies. - Marko Topolnik

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.