Generieren einer hash-Summe für mehrere Ganzzahlen
Stehe ich vor dem problem, dass mehrere ganze zahlen, und ich habe zu generieren mit Ihnen. Zum Beispiel.
Int 1: 14
Int 2: 4
Int 3: 8
Int 4: 4
Hash Sum: 43
Habe ich einige Einschränkung in der Werte, der höchste Wert, und das Attribut haben kann, ist 30, die addition aller von Ihnen ist immer 30. Und die Attribute sind immer positiv.
Der Schlüssel ist, dass ich möchte, zu generieren, die denselben hash-Summe für ähnliche zahlen, zum Beispiel, wenn ich die ganzen zahlen, 14, 4, 10, 2 soll ich dann zu erzeugen, die denselben hash-Summe, in dem Fall oben 43. Aber natürlich, wenn die zahlen sind sehr unterschiedlich (4, 4, 2, 20), dann hätte ich einen anderen hash-Summe. Es muss auch schnell sein.
Idealerweise möchte ich, dass die Ausgabe der hash-Summe liegt zwischen 0 und 512, und es sollte gleichmäßig verteilt. Mit meinen Einschränkungen die ich haben kann, um 5K verschiedene Möglichkeiten, also das, was ich haben möchte, ist um 10 pro Eimer.
Ich bin sicher, es gibt viele algorithmen, die dies tun, aber ich konnte nicht einen Weg finden, googeln dieses Ding. Kann jemand bitte posten Sie einen Algorithmus, um dies zu tun?.
Einige weitere Informationen
Die ganze Sache mit diesem ist, dass diese ganzen zahlen sind Attribute, die für eine Funktion. Ich will um die Werte zu speichern der Funktion in einer Tabelle, aber ich habe nicht genug Speicher zum speichern der verschiedenen Optionen. Das ist, warum ich generalisieren wollen, auf zwischen ähnlichen Parametern.
Der Grund, warum es 10, 5, 15 sind völlig Verschieden von 5, 10, 15, es ist, weil wenn Sie sich vorstellen, diese in 3d dann beide Punkte sind eine ganz andere Stelle
Einige weitere Informationen 2
Einige Antworten versuchen zu lösen das problem mit der Vermischung. Aber ich denke, das ist nicht so Komplex. Dank der Kommentare habe ich realisiert, dass dies ein clustering-Algorithmus problem. Wenn wir nur 3 Attribute und stellen wir uns vor, das problem in 3d, was ich nur brauche ist, teilen den Raum in Blöcke.
In der Tat das Problem kann mit Regeln dieser Art
if (att[0] < 5 && att[1] < 5 && att[2] < 5 && att[3] < 5)
Block = 21
if ( (5 < att[0] < 10) && (5 < att[1] < 10) && (5 < att[2] < 10) && (5 < att[3] < 10))
Block = 45
Das problem ist, dass ich brauche eine schnelle und eine Allgemeine Art und Weise zu erzeugen, die ifs-ich kann nicht schreiben Sie alle Möglichkeiten.
- Sie wollen also eine schlechte hash-Funktion? (high-Kollision, nicht-gleichmäßige Verteilung)
- Ich weiß nicht, wie die Verwendung einer hash-Funktion in mein problem. Für die hash-Funktion brauche ich nur einen Eingang und ich habe 4.
- Ryan ist richtig, was Sie beschreiben, ist schlechte Eingabe für eine hash-Funktion. Sollten Sie beschreiben Ihr problem, nicht eine Lösung, die Sie wissen, funktioniert nicht.
- Ich weiß immer noch nicht, warum dies ist eine schlechte Eingabe für eine hash-Funktion, können Sie definieren, was schlecht ist Eingabe für eine hash-Funktion?
- Als Eddie sagt, eine hash-Funktion sollte die "Rückkehr eine Anzahl gleichmäßig über die mögliche Werte"; angesichts ähnlicher zahlen sollte es zu unterschiedlichen Ausgang. Das ist der Zweck. Was Sie beschreiben, ist das Gegenteil.
- Clustering ähnliche Werte wäre einfach genug, wenn Sie könnten geclustert werden, um pre-definierten einrastpunkte. Sie scheinen zu wollen, dass dynamische snap-Punkte, die müssen wissen, alle anderen Werte.
- Graham, du hast Recht, das ist genau das gleiche als clustering. Kannst du dies als eine Antwort, mehr zugänglich für andere Benutzer in der Zukunft. Wenn Sie Erfahrung in der cluster-können Sie bitte empfehlen eine Entfernung Messen-Funktion, in der Tat brauche ich nur, die.
- Kennen Sie alle die Werte, die vor der Zeit? Eine distanzfunktion wird nicht viel helfen, wenn Sie nicht Feste Werte haben, zu Messen. Könnten Sie vielleicht auch mehr Informationen bieten, auf das, was die input-und output-zahlen darstellen? Ich aktualisiert meine Antwort basiert auf Vermutungen.
- Hatten Sie Glück auf der Suche nach einer Lösung? Ich bin auch zu lösen versucht eine ähnliche Frage. In meinem Fall habe ich eine Reihe von zahlen in verschiedenen Formen (z.B. eine Reihe von zahlen in die Milliarden, der andere ist in Millionen. Man ist in Kilometer, der andere ist in Meilen. Die eine ist, die aus einem Wikipedia-Tabelle, die andere aus einer anderen Quelle. Jedoch alle das gleiche Konzept darstellen. Zum Beispiel das BIP der Länder.) Ich brauche eine sehr robuste Technik, die erfassen können, die "Semantik" von einer Reihe von zahlen und entscheiden, ob Sie ähnlich sind.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Angesichts der Eingänge a, b, c, und d, jeweils zwischen in-Wert von 0 bis 30 (5 bits), wird Folgendes erzeugt eine Zahl im Bereich von 0 bis 255 (8 bits).
Ob der Allgemeine Ansatz geeignet ist, hängt davon ab, wie die Frage interpretiert wird. Die 3 am wenigsten signifikante bits werden gelöscht, Gruppierung 0-7 in dem gleichen Satz, 8-15 in der nächsten, und so weiter.
Trivial getestet mit:
Die einfache Lösung:
Konvertieren, die ganze zahlen auf Zeichenketten durch Kommas getrennt, und die hash wird die resultierende Zeichenkette mit einem gemeinsamen Hash-Algorithmus (md5, sha, etc).
, Wenn Sie wirklich wollen, um roll-your-own, ich möchte etwas tun wie:
Generieren einen hash berechnen: sum(a[i] * x[i]) mod P
Möchten Sie eine hash-Funktion, die abhängig von der Reihenfolge der Eingänge und wo ähnliche Sätze von zahlen generieren, die denselben hash? Das heißt, Sie wollen 50 5 5 10 und 5 5 10 50 zu generieren unterschiedliche Werte, aber Sie wollen 52 7 4 12 zu erzeugen, die denselben hash-50 5 5 10? Eine einfache Möglichkeit, so etwas zu tun ist:
Dies ist nicht perfekt, aber sollte Ihnen eine Idee, eine Möglichkeit zu implementieren, was Sie wollen. Es wird die Behandlung der Werte 50 - 54 als den gleichen Wert, aber Sie behandeln wird, 49 und 50 verschiedene Werte.
Wenn Sie möchten, dass die hash-unabhängig von der Reihenfolge der Eingabe (also der hash-Wert von 5 10 20 und 20 10 5 sind die gleichen), dann ein Weg dies zu tun ist zu Sortieren das array von Integer-zahlen in aufsteigender Reihenfolge vor der Anwendung des hash. Ein anderer Weg wäre, Sie zu ersetzen
mit
EDIT: Unter Berücksichtigung Ihrer Kommentare in der Antwort auf diese Antwort, es klingt wie mein Versuch oben dienen können, die Ihre Bedürfnisse gut genug. Es ist nicht ideal, noch ideal. Wenn Sie eine hohe Leistung, die Sie haben einige der Forschung und des Experimentierens zu tun.
Zusammenzufassen, die Reihenfolge ist wichtig, so 5 10 20 unterscheidet sich von 20 10 5. Außerdem würden Sie im Idealfall die Speicherung der einzelnen "Vektor" getrennt in Ihrem hash-Tabelle, sondern Griff Raum Einschränkungen, die Sie speichern möchten einige Gruppen von Werten in einer Tabelle Eintrag.
Einer idealen hash-Funktion zurückgeben würde, eine Anzahl gleichmäßig über die möglichen Werte basierend auf Ihrem Tisch Größe. Doing dieses Recht hängt von der erwarteten Größe der Tabelle und der Anzahl und erwarteter maximaler Wert von der Eingabe-Vektor-Werte. Wenn Sie können negative Werte haben, als "Koordinate" Werte, dann kann dies beeinflussen, wie Sie berechnen Ihren hash. Wenn Ihre Palette von input-Werte und die hash-Funktion ausgewählt, beträgt die maximale hash-Wert ist kleiner als Ihre hash-Tabelle der Größe, dann müssen Sie ändern Sie den hash-Funktion zu erzeugen, die eine größere hash-Wert.
Möchten Sie vielleicht zu versuchen, mit Vektoren zu beschreiben, jede Zahl setzen, die als der hash-Wert.
BEARBEITEN:
Da bist du nicht der Beschreibung, warum Sie wollen nicht zu laufen, die Funktion selbst, ich vermute, es ist die lange Laufzeit. Da Sie noch nicht beschrieben, wird die Breite aus dem argument setzen.
Wenn jeder Wert erwartet wird, eine vollständige lookup-Tabelle in einer Datenbank könnte schneller sein.
Wenn Sie erwarten, dass wiederholte Aufrufe mit gleichen Argumenten und insgesamt geringe variation, dann könnte man schauen,memoizing, so dass nur der erste Lauf für ein argument ist teuer, und jede weitere Anfrage ist schnell, mit weniger Speicherverbrauch.
Würden Sie brauchen, um zu definieren, was du meinst mit "ähnlich". Hashes sind in der Regel entwickelt, um erstellen Sie einzigartige Ergebnisse, die aus einmaligen Eingabe.
Ein Ansatz wäre es, normalisieren Sie Ihre Eingabe und generieren einen hash aus den Ergebnissen.
Erzeugung der gleichen hash-Summe genannt wird, eine Kollision, und das ist eine schlechte Sache für einen hash zu haben. Es macht es weniger nützlich.
Wenn Sie möchten, dass ähnliche Werte geben die gleiche Ausgabe haben, können Sie teilen Sie die Eingabe, indem jedoch nahe, dass Sie wollen, um Sie zu zählen. Wenn die Reihenfolge einen Unterschied macht, verwenden Sie einen anderen Teiler für jede Zahl. Die folgende Funktion tut das, was Sie beschreiben:
Dies ist kein hash, aber nicht das, was Sie beschreiben.
Sie wollen,geometrische hashing. Im "standard" - hashing-Sie wollen
Mit geometrischen hashing Sie susbtitute Nummer 3 mit etwas whihch ist fast gegenüber, nämlich in der Nähe initial-Werte in der Nähe der hash-Werte.
Anderen Weg, um mein problem mit der multidimesional Skalierung (MS). In MS starten wir mit einer matrix von Elementen, und was wir wollen, ist eine Speicherstelle jedes Element einen N-dimensionalen Raum. Die Reduzierung auf diese Weise die Anzahl der Dimensionen.
http://en.wikipedia.org/wiki/Multidimensional_scaling