2016-04-12 12 views
1

Gegebene (rechteckige) Adjazenzmatrix m, wie Adjazenzliste in q Sprache zu erstellen?[kdb +/q]: Konvertieren Adjazenzmatrix in Adjazenzliste

In QIdioms wiki Ich habe festgestellt Lösung in der k Sprache, die, wenn gibt mir 'vs Fehler durch q Konsole mit k) Befehl ausführen:

m:(1 0 1;1 0 1) 
k) (^m)_vs &,/m 
'vs 

Ergebnis sein sollte:

0 0 1 1 
0 2 0 2 

Dies ist, was Ich konnte in q replizieren:

k) &,/m 
0 2 3 5 
q) where raze m 
0 2 3 5 

k ‚s ^ aka shape Verb ist in q fehlt ich so gerade tat:

k) (^m) 
000b 
000b 
q) 2 3#0b 
000b 
000b 

nun seit:

q) parse "vs" 
k) {x\:y} 

ich erfolglos versucht, beides:

q) (2 3#0b) _vs where raze m 
' 
q) (2 3#0b) _\: where raze m 
'type 

Beachten Sie, dass QIdioms wiki 01 hatfür inverse Problem: von adj.list zu adj.matrix.

Antwort

5

Sie haben Fehler, weil ursprüngliche Q-Idiome in k2 geschrieben sind - eine alte Version von k, die moderne kdb + -Version nicht unterstützt. Eine aktuelle Version von k ist k4 und ist nicht abwärtskompatibel mit k2.

Zum Beispiel X _vs Y wobei X und Y sind ganzzahlige Atome oder Listen in alten k2 verhielt sich wie X vs Ywird verhalten sich in KDB + von 3.4t beginnend 2015.12.13: http://code.kx.com/q/ref/lists/#vs:

Since 3.4t 2015.12.13: For integer types, computes the base representation of Y in the radices X.

ein weiteres Beispiel. In der Tat ^ in k2 war ein Formoperator, aber es ist nicht mehr. In k2 ^m würde 2 3 für eine Matrix m von Ihrem Beispiel zurückgegeben werden, während die aktuelle Implementierung verhält sich wie 's not null, soweit ich verstehe.

Nun zurück zu Ihrer ursprünglichen Frage, "wie Adjazenzliste in q Sprache zu bauen". Eine Möglichkeit, dies zu tun, ist dies:

q)lm:{flip raze(til count x),''where each x} 

oder

k)lm:{+,/(!#x),''&:'x} 

UPDATE: Hier ist, wie es funktioniert. Wenn wir eine Adjazenzliste unter Verwendung eines beliebigen „ausführliche“ Sprache bauen würden wir so etwas tun:

for i = 0 to <number of rows> - 1   <---- (1) 
    for j = 0 to <number of columns> - 1  <---- (2) 
     if M[i;j] <> 0      <---- (3) 
      print i, j 

In einem Array Sprache wie q (1) kann „übersetzt“ werden in til count M weil count die Anzahl der Elemente zurückkehren auf der obersten Ebene, dh die Anzahl der Zeilen.(2) und (3) kombiniert kann durch where each M dargestellt werden. In der Tat geben wir für jede Zeile Positionen von Nicht-Null-Elementen zurück. Bei einer ursprünglichen Matrix m erhalten wir:

til count m -> 0 1 
where each m -> (0 2; 0 2) 

Alles, was wir tun müssen, ist Reihen- und Spaltenindizes beizutreten. Wir können nicht nur ,' verwenden, weil es 0 mit dem ersten 0 2 und 1 mit dem zweiten 0 2 zu (0 0 2; 1 0 2) beitreten wird. Wir müssen eine Stufe tiefer gehen, indem wir jedes Element von links mit jedem Element jedes Elements einer verschachtelten Liste (0 2; 0 2) von rechts verbinden, daher doppelte Apostrophe in ,''.

Ich hoffe, es macht jetzt Sinn.


Persönlich würde ich nicht flip (oder + in k) verwenden, kann ich nicht eine Adjazenzmatrix in dieser Form lesen:

0 0 1 1 
0 2 0 2 

Ich denke, das viel besser lesbar ist:

0 0 
0 2 
1 0 
1 2 

Aber es liegt natürlich an Ihnen.

+0

Igor vielen Dank, das ist hilfreich! Könnten Sie aus pädagogischen Gründen etwas über die einzelnen Schritte der einzeiligen q-Lösung diskutieren? Vor allem "," "Rätsel mich –

+1

Natürlich habe ich meine Antwort aktualisiert. –

+0

Für die Sonderfall-Adjazenzmatrix von 1 Zeile und 1 Spalte ('m: enlist 1') erzeugt die' lm' -Funktion 'type' Fehler:' {raze (til count x), 'wo jeweils x} [enlist 1] '. –