Προγραμματισμός

Γνώση Υπολογιστών >> Προγραμματισμός >  >> Python Προγραμματισμός

Πώς μπορώ να χρησιμοποιήσω αποτελεσματικά τη λειτουργία Permute NP στο Python για να δημιουργήσω όλες τις πιθανές μεταβολές μιας δεδομένης λίστας;

Ενώ το «np.random.permationy» από το Numpy είναι εξαιρετικό για τη δημιουργία μιας * τυχαίας * μετάλλαξης, δεν είναι το εργαλείο για τη δημιουργία * όλων των * μεταβολών. Για να δημιουργήσετε αποτελεσματικά όλες τις πιθανές μεταβολές, θα πρέπει να χρησιμοποιήσετε τη λειτουργία `itertools.permutations 'από την τυπική βιβλιοθήκη. Το Numpy δεν είναι γενικά απαραίτητο για αυτό το έργο και το `itertools` είναι εξαιρετικά βελτιστοποιημένο για την παραγωγή μετάδοσης.

Ακολουθεί μια κατανομή για το πώς να χρησιμοποιήσετε αποτελεσματικά το `itertools.permutations ', μαζί με το γιατί το` np.random.permution` δεν είναι κατάλληλη για τη δημιουργία όλων των παραλλαγών:

1. Χρησιμοποιώντας `itertools.permutations` (η συνιστώμενη προσέγγιση)

`` `Python

Εισαγωγή itertools

def all_permutations (input_list):

"" "

Δημιουργεί όλες τις πιθανές μεταβολές μιας λίστας.

Args:

Input_List:Η λίστα για την οποία θα δημιουργήσει μεταβολές.

Επιστρέφει:

Μια γεννήτρια που αποδίδει πλειάδες, όπου κάθε πλειάδα είναι μια μετάθεση.

"" "

επιστρέψτε itertools.permutations (input_list)

Παράδειγμα χρήσης:

my_list =[1, 2, 3]

μεταβολές =all_permutations (my_list)

για perm στις μεταβολές:

Εκτύπωση (perm) # Εκτυπώνει κάθε μετασχηματισμό ως πλειάδα.

Έξοδος:

(1, 2, 3)

(1, 3, 2)

(2, 1, 3)

(2, 3, 1)

(3, 1, 2)

(3, 2, 1)

Για να μετατρέψετε κάθε μετάθεση σε μια λίστα, χρησιμοποιήστε:

my_list =[1, 2, 3]

μεταβολές =all_permutations (my_list)

για perm στις μεταβολές:

Εκτύπωση (λίστα (perm)) # Εκτυπώνει κάθε μετάθεση ως λίστα

Έξοδος:

[1, 2, 3]

[1, 3, 2]

[2, 1, 3]

[2, 3, 1]

[3, 1, 2]

[3, 2, 1]

για να λάβετε όλες τις μεταβολές ως λίστα με λίστες:

my_list =[1, 2, 3]

Permutations =List (all_permutations (my_list)) # μετατρέψτε τη γεννήτρια σε μια λίστα

list_of_lists =[list (perm) για perm in permutations] # μετατρέψτε την πλειάδα στη λίστα

εκτύπωση (List_of_Lists)

Έξοδος:

[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

`` `

Επεξήγηση:

* `itertools.permutations (input_list)`: Αυτός είναι ο πυρήνας της λύσης. Επιστρέφει έναν * iterator * (συγκεκριμένα, ένα αντικείμενο `permutations '). Ένας iterator είναι αποδοτικός από τη μνήμη επειδή παράγει παραλλαγές κατόπιν αιτήματος, μία κάθε φορά, αντί να τις δημιουργεί όλα ταυτόχρονα στη μνήμη. Αυτό είναι ζωτικής σημασίας για μεγαλύτερες λίστες όπου ο αριθμός των μεταβολών μπορεί να γίνει εξαιρετικά μεγάλος (το n! Μεγαλώνει πολύ γρήγορα).

* γεννήτρια: Η χρήση μιας γεννήτριας (ο iterator) είναι σημαντική για την αποτελεσματικότητα. Εάν μετατρέψετε τη γεννήτρια σε μια λίστα εκ των προτέρων (π.χ. λίστα (itertools.permutations (input_list)) `), θα δημιουργήσετε * όλες τις * μεταβολές αμέσως, γεγονός που μπορεί να οδηγήσει σε προβλήματα μνήμης για μεγαλύτερες λίστες εισροών. Επεξεργαστείτε τις μεταβολές μία προς μία χρησιμοποιώντας ένα "για" βρόχο ".

* `Tuple` output: Το `itertools.permutations 'επιστρέφει κάθε μεταστροφή ως` tuple'. Εάν χρειάζεστε την έξοδο ως λίστα ", μπορείτε να μετατρέψετε την πλειάδα χρησιμοποιώντας τη λίστα (perm)`.

* Αποδοτικότητα: Το `itertools.permutations 'εφαρμόζεται στο C και είναι εξαιρετικά βελτιστοποιημένο για αυτό το έργο. Είναι ο πιο αποτελεσματικός τρόπος για τη δημιουργία μεταβολών στην Python.

2. Γιατί το «np.random.permationation» είναι ακατάλληλο

Το «np.random.permationation» έχει σχεδιαστεί για τη δημιουργία * τυχαίων * παραλλαγών, όχι όλων αυτών. Εδώ γιατί δεν θα λειτουργήσει σωστά για τον προβλεπόμενο σκοπό:

* τυχαία: Δημιουργεί μια ενιαία τυχαία μετάθεση κάθε φορά που το ονομάζετε.

* Καμία εγγύηση όλων των μεταβολών: Για να πάρετε * όλες τις * παραλλαγές με `np.random.permationation`, θα χρειαστεί να το ονομάσετε επανειλημμένα μέχρι να δείτε όλα τα n! δυνατότητες. Δεν υπάρχει τρόπος να γνωρίζετε πότε έχετε εξαντλήσει όλες τις παραλλαγές χωρίς να παρακολουθείτε αυτά που έχετε ήδη δει, κάτι που γίνεται εξαιρετικά περίπλοκο και αναποτελεσματικό. Δεν υπάρχει καμία εγγύηση ότι θα δημιουργήσετε ποτέ κάθε πιθανή μετάθεση με αυτόν τον τρόπο.

* Αναποτελεσματική επανάληψη: Θα δημιουργούσατε πολλές διπλές παραλλαγές πριν τελικά (ίσως ποτέ) να βλέπετε όλα αυτά.

Λανθασμένη (και αναποτελεσματική) προσπάθεια να χρησιμοποιήσετε το `np.random.permution` (μόνο επεξηγηματικούς σκοπούς - μην χρησιμοποιείτε):

`` `Python

Εισαγωγή Numpy ως NP

def enterply_permutations_with_numpy (input_list):

"" "

Μην το χρησιμοποιείτε! Είναι μια λανθασμένη και αναποτελεσματική προσπάθεια

να δημιουργηθεί όλες οι μεταβολές χρησιμοποιώντας το np.random.permation.

"" "

seen_permutations =set ()

all_perms =[]

n =len (input_list)

factorial_n =np.math.factorial (n) # Αυτό μπορεί να ξεχειλίσει!

ενώ το len (seen_permutations) perm =tuple (np.random.permation

Εάν δεν είναι perm σε deed_permutations:

seen_permutations.add (perm)

all_perms.append (λίστα (perm))

επιστροφή all_perms

Μην χρησιμοποιείτε αυτό το παράδειγμα! Είναι μόνο για την επίδειξη του γιατί είναι λανθασμένη.

my_list =[1, 2, 3]

permutations =enterper_all_permutations_with_numpy (my_list) # ενδεχομένως κρέμεται ή χρησιμοποιεί υπερβολική μνήμη.

εκτύπωση (μεταβολές)

`` `

Προβλήματα με την απόπειρα Numpy:

* Θέματα μνήμης: Το σύνολο `seen_permutations 'θα αναπτυχθεί γρήγορα σε ένα τεράστιο μέγεθος, ενδεχομένως να υπερβαίνει τη διαθέσιμη μνήμη, ειδικά για ελαφρώς μεγαλύτερες λίστες.

* Αποδοτικότητα: Η συνθήκη βρόχου `len (seen_permutations) * Εσφαλτικότητα: Είναι δυνατόν (αν και στατιστικά απίθανο) για τον βρόχο να τερματίσει πρόωρα ή να μην τερματίσει ποτέ λόγω της τυχαίας φύσης της παραγωγής της μετάθεσης.

* Μετατροπή πλειάδας: Η μετατροπή των θηλυκών συστοιχιών σε πλειάδες και πίσω στους καταλόγους είναι ένα γενικό εξόδους που αποφεύγει το `itertools '.

Συνοπτικά:

Για τη δημιουργία όλων των πιθανών μεταβολών μιας λίστας στο Python, χρησιμοποιείτε πάντα το `itertools.permutations ' . Είναι ο σωστός, πιο αποτελεσματικός και πυθονικός τρόπος για την επίλυση αυτού του προβλήματος. Αποφύγετε τη χρήση του `np.random.permution 'για το σκοπό αυτό, καθώς έχει σχεδιαστεί για διαφορετική εργασία και θα οδηγήσει σε εσφαλμένο και αναποτελεσματικό κώδικα.

Συναφής σύστασή

Πνευματικά δικαιώματα © Γνώση Υπολογιστών Όλα τα δικαιώματα κατοχυρωμένα