Ich möchte die Anzahl der 2D-Arrays mit nur 1 und 0 Einträgen zählen, die ein disjunktes Paar von disjunkten Paaren von Zeilen haben, die gleiche Vektorsummen haben. Für eine 4 x 4-Matrix erreicht der folgende Code dies, indem er einfach alle über iteriert und nacheinander testet.
%Vor%Die Ausgabe ist 3136.
Das Problem dabei ist, dass es 2 ^ (4 ^ 2) Iterationen verwendet und ich möchte es für n bis 8 ausführen. Gibt es eine klügere Möglichkeit, diese zu zählen, ohne über alle Matrizen zu iterieren? Zum Beispiel scheint es sinnlos, Permutationen der gleichen Matrix immer wieder zu erstellen.
Berechnet in ungefähr einer Minute auf meinem Rechner mit CPython 3.3:
%Vor%Code, basierend auf Memo-Inclusion-Exclusion:
%Vor%Sie können diesen unter "besser als nichts" ablegen ;-) Hier ist einfacher Python3-Code, der das Problem ein wenig umdenkt. Vielleicht könnten nackte Tricks es wesentlich beschleunigen, aber schwer zu sehen, wie.
range(2**n)
. Also das Array ist nur ein Tupel von ganzen Zahlen. combinations_with_replacement()
eindeutig sind. Dies reduziert die Anzahl der Fahrten auf der äußeren Schleife von 2**(n**2)
auf (2**n+n-1)-choose-n)
. Eine enorme Reduktion, aber immer noch ... Hier ist der Code:
%Vor%Das reichte aus, um Ergebnisse über n = 6 zu finden, obwohl es lange gedauert hat, das letzte zu beenden (wie lange? weiß nicht - habe es nicht - in der Größenordnung von einer Stunde - "long") Zeit "ist relativ ;-)):
%Vor%BEARBEITEN - Entfernen einer unnötigen Indizierung
Eine schöne Beschleunigung durch Ändern der Hauptfunktion zu diesem:
%Vor%BEARBEITEN - beschleunigt den Summentest
Das ist unbedeutend, aber da dies der bisher beste Ansatz auf dem Tisch zu sein scheint, könnte es auch etwas mehr aus ihm herausquetschen. Wie zuvor bemerkt, kann, da jede Summe in range(3)
ist, jedes Tupel von Summen durch eine ganze Zahl ersetzt werden (Betrachten des Tupels als Geben der Ziffern einer Basis-3-Ganzzahl). Ersetzen Sie calc_row_pairs()
like so:
Ich bin sicher, dass numpy einen viel schnelleren Weg hat, aber die von calc_row_pairs()
benötigte Zeit ist unbedeutend, also warum? Übrigens, der Vorteil dabei ist, dass die Inner-Loop ==
-Tests von dem Vergleich von Tupeln mit dem Vergleich von kleinen ganzen Zahlen abweichen. Plain Python profitiert davon, aber ich wette, Pypy könnte noch mehr davon profitieren.
Keine direkte Antwort auf Ihre Frage, aber wie gesagt, ich glaube, Sie können sicher vergessen, alle Matrizen für jedes signifikante n erschöpfend zu testen. Das Problem eignet sich jedoch gut für eine stochastische Charakterisierung. Interessanterweise sind Tripelsummen unter bestimmten Bedingungen häufiger als Doppelsummen! Die Wahrscheinlichkeit, einen Treffer zu bekommen, scheint eine ziemlich einfache (monotone) Funktion von sowohl n als auch m zu sein, aber keine Überraschungen.
Tags und Links python algorithm math performance numpy