Finden Sie eindeutige Zeilen eines Zellen-Arrays unter Berücksichtigung aller möglichen Permutationen in jeder Zeile

8

Ich habe das Zellenarray A der Dimension m * k .

Ich möchte die Zeilen von A eindeutig bis zu einer Ordnung der k-Zellen behalten.

Der "knifflige" Teil ist "bis zu einer Ordnung der k-Zellen" : Betrachten Sie die k -Zellen in der i -ten Zeile von A , A(i,:) ; Es könnte eine Zeile geben j von A , A(j,:) , das ist äquivalent zu A(i,:) bis zu einer Neuordnung seiner k -Zellen, was bedeutet, dass zum Beispiel, wenn k=4 das sein könnte:

%Vor%

Was ich gerade mache ist:

%Vor%

Es funktioniert, aber es ist zu langsam. Ich hoffe, dass es etwas schneller gibt, das ich benutzen kann.

    
user3285148 10.10.2016, 09:47
quelle

3 Antworten

6

Ich würde gerne eine andere Idee vorschlagen, die eine gewisse konzeptionelle Ähnlichkeit mit erfan hat a>. Meine Idee verwendet Hash-Funktionen und speziell die GetMD5 FEX-Einreichung .

Die Hauptaufgabe besteht darin, jede Zeile in A auf einen einzelnen repräsentativen Wert (wie einen Zeichenvektor) zu reduzieren und dann eindeutige Einträge dieses Vektors zu finden.

Gemessen an der Benchmark im Vergleich zu den anderen Vorschlägen, schneidet meine Antwort nicht so gut ab wie eine der Alternativen, aber ich denke, ihre raison d'être liegt in der Tatsache, dass sie vollständig ist Datentypen Agnostiker (innerhalb der Grenzen der GetMD5 1 ), dass der Algorithmus ist sehr einfach zu verstehen, es ist ein Drop-in Ersatz, wie es auf A funktioniert, und dass die daraus resultierenden Array ist exakt gleich dem von der ursprünglichen Methode erhaltenen Array. Natürlich erfordert dies einen Compiler, um zu arbeiten, und es besteht das Risiko von Hash-Kollisionen (die das Ergebnis in SEHR SEHR seltenen Fällen beeinflussen könnten).

Hier sind die Ergebnisse einer typischen Ausführung auf meinem Computer, gefolgt vom Code:

%Vor%

%Vor%

1 - Wenn kompliziertere Datentypen gehashed werden sollen, kann man den DataHash FEX Vorlage statt dessen, was etwas langsamer ist.

    
Dev-iL 16.10.2016, 13:04
quelle
4

Angabe des Problems: Die ideale Wahl zur Identifizierung eindeutiger Zeilen in einem Array besteht in der Verwendung von C = unique(A,'rows') . Aber es gibt zwei Hauptprobleme, die uns daran hindern, diese Funktion in diesem Fall zu verwenden. Erstens möchten Sie beim Vergleich mit anderen Zeilen alle möglichen Permutationen jeder Zeile zählen. Wenn A 5 Spalten hat, bedeutet das Überprüfen von 120 verschiedenen Umordnungen pro Zeile! Sounds unmöglich.

Das zweite Problem bezieht sich auf unique selbst; Es akzeptiert keine Zellen außer Zellenarrays von Zeichenvektoren . Sie können A nicht einfach an unique übergeben und bekommen, was Sie erwarten.

Warum suchen Sie eine Alternative? Wie Sie wissen, ist es momentan sehr langsam:

%Vor%

Meine Lösung:

  1. Erzeugt ein anderes Zellen-Array, das dieselben Zellen enthält, aber in eine Zeichenfolge konvertiert wurde ( STR ).
  2. Hier finden Sie den Index aller eindeutigen Elemente ( id ).
  3. Erzeuge die zugehörige Matrix mit den eindeutigen Indizes und sortiere Zeilen ( IC ).
  4. Finde eindeutige Zeilen ( rows ).
  5. Sammeln Sie die entsprechenden Zeilen von A ( C ).

Und das ist der Code:

%Vor%

Leistungsprüfung:

%Vor%

Obwohl die Initialisierung etwas mehr Zeit und Speicher benötigt, ist diese Methode beim Finden eindeutiger Zeilen unter Berücksichtigung aller Permutationen sehr viel schneller. Die Ausführungszeit ist fast unempfindlich gegenüber der Anzahl der Spalten in A .

    
erfan 13.10.2016 16:35
quelle
3

Es scheint, dass G ein irreführender Punkt ist. Hier ist das Ergebnis von nchoosek für eine kleine Zahl

%Vor%

erste Zeile ist Komplement der letzten Zeile

zweite Zeile ist ein Komplement von eins vor der letzten Zeile

.....

Wenn wir also die Zeilen {1 , 2} von G extrahieren, dann ist das Komplement die Zeilen {3, 4} und so weiter. Mit anderen Worten, wenn wir annehmen, dass die Anzahl der Zeilen von G 4 ist, dann ist G(idx(1,:),:) das Komplement von G(idx(end,:),:) .

Da Zeilen von G alle eindeutig sind, haben alle A{m,n} s immer dieselbe Größe.

A{p,1} und A{p,2} sind Komplemente voneinander. und die Größe der eindeutigen Zeilen von A ist size(idx,1)/2

Also keine Notwendigkeit für eine Schleife oder einen weiteren Vergleich:

%Vor%

Aktualisieren : Die obige Methode funktioniert am besten, wenn die Idee darin besteht, A1 von A anders als GI zu erhalten, schlagen Sie folgende Methode basierend auf erfan . Anstatt Array in String umzuwandeln, können wir direkt mit dem Array arbeiten:

%Vor%

Da ich Octave verwende, kann ich momentan keine mex-Datei laufen lassen, dann kann ich die Dev-iL Methode nicht testen

Ergebnis :

%Vor%

Online-Demo

    
rahnema1 16.10.2016 07:12
quelle