Algoritmo para calcular el conjunto de soluciones de una sola ecuación simple con dos variables
Frecuentes
Visto 2,538 veces
13
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?
4 Respuestas
7
Consideremos el problema más general
- Para dos enteros coprimos positivos
a
yb
, dado un entero positivon
, encuentra la pareja(x,y)
de enteros no negativos tales quea*x + b*y = n
con mínimox
. (Si hay uno. No es necesario que lo haya, por ejemplo7*x + 4*y = 5
no tiene solución con no negativox
yy
.)
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
6
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
2
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
1
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 java algorithm math or haz tu propia pregunta.
Tu dices
If the equation 7*i + 4*y = n holds
Obtienes del bucle, pero ¿qué es y? - msam¿Hay un límite superior en X e Y? Si es así, haz búsquedas binarias para alcanzar el éxito. - Tony Ennis
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. - amit
Esto pide una solución para CodeChef mayo 2012 problema de concurso DIVPAIR :-(- Betlista
@Betlista he planteó el problema en meta si desea comentar más - AakashM