Wie kann ich das generieren einer Karte-Schlüssel für diesen Vektor in MATLAB?
Ich habe eine Funktion, die Suche auf eine Anzahl von Elementen. Jedes element ist von der form von einer 8x1-Spalten-Vektor. Jeder Eintrag im Vektor ist eine ganze Zahl kleiner als 1000. Jedes mal, wenn ich sehe, wie ein Vektor, möchte ich hinzufügen, dass es eine Liste der "bereits gesehen" - Vektoren, nach der überprüfung, um zu sehen, dass der Vektor nicht bereits auf dieser Liste. Die Funktion wird prüfen, die auf der Reihenfolge der ~100,000 solcher Vektoren.
Ursprünglich wollte ich mit ismember(v', M, 'rows')
, aber fand, dass das sehr langsam. Danach habe ich versucht:
found = containers.Map('KeyType', 'double', 'ValueType', 'any');
Dann jedes mal, wenn ich überprüfen eine neue Vektor - v
berechnen:
key = dot(v, [1000000000000000000000 1000000000000000000 1000000000000000 ...
1000000000000 1000000000 1000000 1000 1]);
Dann schauen Sie isKey(found, key)
. Wenn der Schlüssel nicht im container, dann found(key) = 1
.
Scheint dies wie eine ziemlich miese Lösung, auch wenn es läuft deutlich schneller als ismember
. Jede Hilfe/Anregungen würde sehr geschätzt werden.
EDIT: Vielleicht wäre es besser mat2str
um den Schlüssel zu generieren, anstatt diese dumme dot product?
- Sie haben, Sie zu verarbeiten, nacheinander? Sie konnte verketten alle Vektoren in einem 100.000-by-8-array z und call unique(z, 'Zeilen', 'first') auf, um die unterschiedlichen Werte und Indizes des ersten Vorkommens der einzelnen.
- Das dot-Produkt-hash ist schneller als mat2str, aber Sie haben hash-Kollisionen aufgrund von Rundungsfehlern, da die hash-Bereich fällt die relative Präzision der
double
geben. E. g. die hashes für die [999 1 1 1 1 1 1 1] und [999 1 1 1 1 1 1 2] durch [999 1 1 1 1 1 1 100] kollidieren werden. Mat2str basierte hashes haben dieses problem nicht. Und mat2str ist ziemlich schnell hier ~80 usec für mich. Versuchen Sie, Zeitmessung Ihren Kandidaten-hash-Funktionen mit tic/toc, und das Profil der ganzen Sache. Klingt vernünftig zu mir.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der einfachste Weg, um einen Schlüssel erzeugen/hash in deinem Fall wäre zu einfach konvertieren den Vektor von integer-Werte zu einem Zeichen-array verwenden
char
. Da Ihr integer-Werte nie über 1000, undchar
akzeptieren können numerische Werte von 0 bis 65535 (entsprechende Unicode-Zeichen), dieser wird Ihnen eine einzigartige 8-stellige Schlüssel für jede einzigartige 8-by-1-Vektor. Hier ist ein Beispiel:deine Idee ist gut. aber Sie brauchen, um zu finden, eine bessere hash-Funktion. verwenden Sie einige standard-hash-Funktion.
Es ist eine Umsetzung von 'sha' algorithmen, die Sie zu sehen:
http://www.se.mathworks.com/matlabcentral/fileexchange/31795-sha-algorithms-160224256384-512
Wenn Sie den sha-Algorithmus langsam, dann kann man wahrscheinlich resort zu einigen tricks. Eine, an die ich gerade denke ist folgende:
sollte dies wohl funktionieren, aber Sie werden zu prüfen haben.
java.security.MessageDigest
Klasse direkt aus Matlab, mittypecast(v,'int8')
zu konvertieren Matlabdouble
array an Javabyte[]
, dann dec2hex die Antwort, wenn Sie es brauchen, in string-form. Es ist wahrscheinlich schneller und richtiger, dass die fileexchange-version.java.security.MessageDigest
ist wahrscheinlich nicht schneller sein, zumindest, Sie haben zu tun, einige tweaks für die. Für die Referenz können Sie die folgenden links: mathworks.com/matlabcentral/newsreader/view_thread/281221 mathworks.com/matlabcentral/newsreader/view_thread/...Nicht wirklich in hashing, aber immer noch glauben gefunden zu haben, der einfachste Weg, um Ihr problem zu lösen.
Dieser läuft etwa 10x schneller als ismember.