Таким образом, логика для сортировки в обратном порядке числа, и предположим , что список чисел л и сумма будет сформирована в s .
for i in b:
if(a(round(n-i,2),b[b.index(i)+1:])):
r.append(i)
return True
return False
Затем, мы проходим через эту петлю и число выбирается из л в порядке , и пусть говорят , что это я . есть 2 возможных случая либо я это часть суммы или нет. Таким образом, мы предполагаем , что я является частью решения , и тогда задача сводится к л существо l[l.index(i+1):]и ей существо си поэтому, если наша функция а (л, с) , то мы называем a(l[l.index(i+1):] ,s-i). и если я не являюсь частью с , то мы должны сформировать S из l[l.index(i+1):]списка. Так что похоже в обоих случаях, только изменение , если я является частью с, только тогда s = Si и в противном случае S = s.
Теперь, чтобы уменьшить эту проблему таким образом, что в случае чисел в л больше, чем с мы удаляем их, чтобы уменьшить сложность до тех пор, пока л пусто, и в этом случае числа, которые выбраны не являются частью нашего решения, и мы возвращаемся ложным.
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
обратите внимание, в цикле, если использовали b..but б наш список only.and я закругленный везде, где это возможно, так что мы не должны получить неправильный ответ из-за вычисления с плавающей запятой в 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)
это решение работает fast.more быстрее, чем один пояснено выше. Однако это работает только для положительных чисел. Однако и это хорошо работает, если есть решение только в противном случае потребуется много времени, чтобы выйти из петель.
пример запуска, как это позволяет сказать,
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
просто чтобы дать сравнение, которое я выбежала на моем компьютере, который не так хорошо. с помощью
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]
а также
s = 2000
мой цикл побежал 1018 раз и 31 мс.
и предыдущий цикл кода побежал 3415587 раз и взял где-то около 16 секунд.
Однако в случае, если решение не существует мой код побежал более чем несколько минут, поэтому я остановил его и предыдущий код побежал только около около 17 мсов и предыдущий код работает с отрицательными числами также.
поэтому я, что некоторые улучшения могут быть сделаны.