Por lo tanto, la lógica es inversa a ordenar los números, y supongamos que la lista de números está l y la suma de formarse es s .
for i in b:
if(a(round(n-i,2),b[b.index(i)+1:])):
r.append(i)
return True
return False
a continuación, vamos a través de este bucle y un número se selecciona entre l en orden y dejar que dicen que es i . hay 2 casos posibles o bien i es la parte de la suma o no. Por lo tanto, suponemos que i es parte de la solución y entonces el problema se reduce a l bienestar l[l.index(i+1):]y s ser si es así, si nuestra función es un (l, s) entonces llamamos a(l[l.index(i+1):] ,s-i). y si i no es una parte de s entonces tenemos que formar s de la l[l.index(i+1):]lista. Por lo tanto, es similar en los dos casos, único cambio es que si i es parte de s, entonces s = Si y de otro tipo s = s solamente.
ahora para reducir el problema de manera que en el número de casos en l son mayores que s les quitamos a reducir la complejidad hasta l está vacía y en ese caso los números que se seleccionan no son una parte de nuestra solución y nos devuelven false.
if(len(b)==0):
return False
while(b[0]>n):
b.remove(b[0])
if(len(b)==0):
return False
y en el caso l tiene solamente 1 elemento dejó entonces o bien puede ser parte de s entonces volvemos verdadero o no lo es entonces volvemos falsa y bucle a pasar por otro número.
if(b[0]==n):
r.append(b[0])
return True
if(len(b)==1):
return False
en cuenta en el bucle si han utilizado b..but b es nuestra lista only.and i han redondeado siempre que sea posible, por lo que no hay que obtener una respuesta equivocada debido a cálculos de punto flotante en Python.
r=[]
list_of_numbers=[61.12,13.11,100.12,12.32,200,60.00,145.34,14.22,100.21,14.77,214.35,200.32,65.43,0.49,132.13,143.21,156.34,11.32,12.34,15.67,17.89,21.23,14.21,12,122,134]
list_of_numbers=sorted(list_of_numbers)
list_of_numbers.reverse()
sum_to_be_formed=401.54
def a(n,b):
global r
if(len(b)==0):
return False
while(b[0]>n):
b.remove(b[0])
if(len(b)==0):
return False
if(b[0]==n):
r.append(b[0])
return True
if(len(b)==1):
return False
for i in b:
if(a(round(n-i,2),b[b.index(i)+1:])):
r.append(i)
return True
return False
if(a(sum_to_be_formed,list_of_numbers)):
print(r)
esta solución funciona fast.more rápida de una explicado anteriormente. Sin embargo, esto sólo funciona para los números positivos. Sin embargo también funciona bien si hay una solución única de lo contrario se necesita mucho tiempo para salir de bucles.
un ejemplo de ejecución es como esto permite decir
l=[1,6,7,8,10]
and s=22 i.e. s=1+6+7+8
so it goes through like this
1.) [10, 8, 7, 6, 1] 22
i.e. 10 is selected to be part of 22..so s=22-10=12 and l=l.remove(10)
2.) [8, 7, 6, 1] 12
i.e. 8 is selected to be part of 12..so s=12-8=4 and l=l.remove(8)
3.) [7, 6, 1] 4
now 7,6 are removed and 1!=4 so it will return false for this execution where 8 is selected.
4.)[6, 1] 5
i.e. 7 is selected to be part of 12..so s=12-7=5 and l=l.remove(7)
now 6 are removed and 1!=5 so it will return false for this execution where 7 is selected.
5.)[1] 6
i.e. 6 is selected to be part of 12..so s=12-6=6 and l=l.remove(6)
now 1!=6 so it will return false for this execution where 6 is selected.
6.)[] 11
i.e. 1 is selected to be part of 12..so s=12-1=1 and l=l.remove(1)
now l is empty so all the cases for which 10 was a part of s are false and so 10 is not a part of s and we now start with 8 and same cases follow.
7.)[7, 6, 1] 14
8.)[6, 1] 7
9.)[1] 1
sólo para dar una comparación que me encontré en mi equipo que no es tan bueno. utilizando
l=[61.12,13.11,100.12,12.32,200,60.00,145.34,14.22,100.21,14.77,214.35,145.21,123.56,11.90,200.32,65.43,0.49,132.13,143.21,156.34,11.32,12.34,15.67,17.89,21.23,14.21,12,122,134]
y
s = 2000
mi bucle funcionó 1018 veces y 31 ms.
y el bucle de código anterior corrió 3415587 veces y tuvo algún lugar cerca de 16 segundos.
Sin embargo, en caso no existe una solución mi código corrió más de unos minutos, así que se detuvo y corrió código anterior sólo cerca alrededor de 17 ms y el código anterior funciona con números negativos también.
por lo que me algunas mejoras puede hacerse.