Έτσι, η λογική είναι να αντιστραφεί το είδος τους αριθμούς, και ας υποθέσουμε ότι ο κατάλογος των αριθμών l και ποσό που πρόκειται να σχηματιστεί είναι s .
for i in b:
if(a(round(n-i,2),b[b.index(i)+1:])):
r.append(i)
return True
return False
Στη συνέχεια, περνάμε μέσα από αυτό το βρόχο και ένας αριθμός επιλέγεται από l σε σειρά και ας λένε ότι είναι i . υπάρχουν 2 πιθανές περιπτώσεις είτε i είναι το μέρος του ποσού ή όχι. Έτσι, υποθέτουμε ότι i είναι μέρος της λύσης και, στη συνέχεια, το πρόβλημα μειώνει σε l ον l[l.index(i+1):]και s ον si έτσι, εάν η λειτουργία μας είναι (l, s), τότε λέμε a(l[l.index(i+1):] ,s-i). και αν εγώ δεν αποτελεί μέρος του s τότε θα πρέπει να σχηματίσουν s από τη l[l.index(i+1):]λίστα. Έτσι είναι παρόμοια και στις δύο περιπτώσεις, μόνο η αλλαγή είναι αν μπορώ να αποτελεί μέρος του s, τότε s = si και τα άλλα s = s μόνο.
τώρα για να μειώσει το πρόβλημα έτσι ώστε σε αριθμούς περίπτωση l είναι μεγαλύτερες από ό, τι s να τους αφαιρέσει για να μειωθεί η πολυπλοκότητα μέχρι l είναι άδειο και σε αυτή την περίπτωση οι αριθμοί που επιλέγονται δεν αποτελούν μέρος της λύσης μας και επιστρέφουμε ψευδείς.
if(len(b)==0):
return False
while(b[0]>n):
b.remove(b[0])
if(len(b)==0):
return False
και σε περίπτωση ιβ έχει μόνο 1 στοιχείο αριστερά, στη συνέχεια, είτε μπορεί να είναι μέρος του s τότε θα επιστρέψει αλήθεια ή δεν είναι, τότε return false και βρόχο θα περάσουν από άλλο αριθμό.
if(b[0]==n):
r.append(b[0])
return True
if(len(b)==1):
return False
Σημειώστε στο βρόχο αν έχουν χρησιμοποιηθεί b..but b είναι η λίστα μας 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 ms.
και τα προηγούμενα κωδικό βρόχο έτρεξε 3415587 φορές και πήρε κάπου κοντά 16 δευτερόλεπτα.
Ωστόσο, σε περίπτωση που δεν υπάρχει λύση κωδικό μου έτρεξε περισσότερο από μερικά λεπτά, γι 'αυτό σταμάτησε και η προηγούμενη κωδικό έτρεξε μόνο κοντά περίπου 17 ms και τα προηγούμενα κωδικός λειτουργεί με αρνητικούς αριθμούς επίσης.
γι 'αυτό το πράγμα κάποιες βελτιώσεις μπορούν να γίνουν.