Ich habe Zahlen in einem bestimmten Bereich (normalerweise von 0 bis etwa 1000). Ein Algorithmus wählt einige Zahlen aus diesem Bereich aus (etwa 3 bis 10 Zahlen). Diese Auswahl wird sehr oft gemacht, und ich muss prüfen, ob eine Permutation der gewählten Zahlen bereits ausgewählt wurde.Gute Hash-Funktion für Permutationen?
z. B. ein Schritt wählt [1, 10, 3, 18]
und ein anderer [10, 18, 3, 1]
dann kann die zweite Auswahl verworfen werden, weil es eine Permutation ist.
Ich muss diese Überprüfung sehr schnell machen. Jetzt setze ich alle Arrays in eine Hashmap und benutze eine benutzerdefinierte Hash-Funktion: fasst einfach alle Elemente zusammen, also 1 + 10 + 3 + 18 = 32, und auch 10 + 18 + 3 + 1 = 32. Für equals verwende ich ein Bitset, um schnell zu prüfen, ob Elemente in beiden Mengen enthalten sind (ich brauche keine Sortierung bei Verwendung des Bitsets, aber es funktioniert nur, wenn der Zahlenbereich bekannt und nicht zu groß ist).
Das funktioniert zwar, kann aber viele Kollisionen erzeugen, daher wird die equals() -Methode oft aufgerufen. Ich habe mich gefragt, ob es einen schnelleren Weg gibt, nach Permutationen zu suchen?
Gibt es irgendwelche guten Hash-Funktionen für Permutationen?
UPDATE
Ich habe ein wenig Benchmark getan: alle Kombinationen von Zahlen im Bereich von 0 bis 6 und Feldlänge 1 bis 9. Bereich erzeugen sollte Es gibt 3003 mögliche Permutationen und eine gute Hash erzeugt schließen zu diesen vielen verschiedenen Hashes (I verwenden 32-Bit-Zahlen für die Hash):
- 41 verschiedene Hashes für gerade hinzufügen (so gibt es viele Kollisionen)
- 8 verschiedene Hashes für XOR-Verknüpfung Werte zusammen
- 286 verschiedene Hashes für
- 3003 unterschiedliche Hashes für (R + 2e) und Multiplikation als abc hat Multiplikation vorgeschlagen (mit 1779033703 für R)
So Hash-ABC kann sehr schnell berechnet werden und ist viel besser als der ganze Rest. Vielen Dank!
PS: Ich möchte die Werte nicht sortieren, wenn ich nicht muss, denn das würde zu langsam werden.
Ich bin nicht davon überzeugt, dass Ihr Ansatz, die Werte zu summieren, um einen Hash zu erstellen, so funktioniert, wie Sie es beabsichtigen. Sicher 1 + 10 + 3 + 18 = 10 + 18 + 3 + 1 = 32, aber auch 1 + 12 + 3 + 16. –
@Paul, das ist der Grund, warum er einen Sortier-und-Vergleich durchführt, wenn der Wert gleich ist. – pierrotlefou
Es stellte sich heraus mein Algorithmus war halb gebacken (1,2,3) kollidiert mit (1,6,7) und viele andere Kollisionen sind möglich. Ich zappte die Post, um Verwirrung zu vermeiden. –