Ich habe in Scala ein Diagramm mit der GraphX-API erstellt. In meinem Graph, hat jeder Knoten eine LinkedHashMap[Int, ListBuffer[ListBuffer[Int]]]
als Attribut: jedes Paar (Schlüssel, Wert) des LinkedHashMap
darstellt:Entfernen von Elementen aus LinkedHashMap und ListBuffer von ListBuffer, die als Vertex-Attribute in einer Graphenstruktur verwendet werden
- Schlüssel: id eines Knotens - als
Int
- Wert: alle möglichen Wege zu erreichen der Knoten - jeder Weg ist ein
ListBuffer[Int]
, so habe ich eineListBuffer
vonListBuffer[Int]
(I Pregel
verwendet habe, die LinkedHashMap
s zu erstellen). Also, ich möchte den Fall eines Entfernens eines Knotens aus dem Graph implementieren. Was ich zu tun ist:
- Entfernen in jedem
LinkedHashMap
, das Element mit dem Schlüssel == id_of_the_node - Entfernen in jedem
ListBuffer[ListBuffer[Int]]
, die Listen (Pfade), die die gelöschten Knoten (der Pfad enthält nicht mehr vorhanden).
Angenommen, ich habe die folgenden Knoten (Ich werde die anderen weglassen):
Knoten 1: (1,Map(5 -> ListBuffer(ListBuffer(1, 3, 5), ListBuffer(1, 4, 5)), 6 -> ListBuffer(ListBuffer(1, 3, 6)), 3 -> ListBuffer(ListBuffer(1, 3)), 4 -> ListBuffer(ListBuffer(1, 4)), 1 -> ListBuffer(ListBuffer(1))))
Knoten 2: (2,Map(5 -> ListBuffer(ListBuffer(2, 1, 3, 5), ListBuffer(2, 1, 4, 5)), 6 -> ListBuffer(ListBuffer(2, 1, 3, 6)), 3 -> ListBuffer(ListBuffer(2, 1, 3)), 4 -> ListBuffer(ListBuffer(2, 1, 4)), 1 -> ListBuffer(ListBuffer(2, 1)), 2 -> ListBuffer(ListBuffer(2))))
Knoten 3: (3,Map(5 -> ListBuffer(ListBuffer(3, 5)), 6 -> ListBuffer(ListBuffer(3, 6)), 3 -> ListBuffer(ListBuffer(3))))
Und angenommen, Ich möchte den Knoten 3
von myGraph
löschen. Dann sollte die Knoten Attribute werden:
Knoten 1: (1, Map(5 -> ListBuffer(ListBuffer(1, 4, 5)), 4 -> ListBuffer(ListBuffer(1, 4)), 1 -> ListBuffer(ListBuffer(1))))
Knoten 2: (2, Map(5 -> ListBuffer(ListBuffer(2, 1, 4, 5)), 4 -> ListBuffer(ListBuffer(2, 1, 4)), 1 -> ListBuffer(ListBuffer(2, 1)), 2 -> ListBuffer(ListBuffer(2))))
Knoten 3: (-1, LinkedHashMap[ListBuffer[ListBuffer[]]]())
- ich weiß nicht, wie ein leeres LinkedHashMap[ListBuffer[ListBuffer[Int]]]
zuweisen.
Ich habe die folgende Methode definiert:
def del(nodeToDelete: Int, vertexMap: collection.mutable.LinkedHashMap[Int,ListBuffer[ListBuffer[Int]]]): collection.mutable.LinkedHashMap[Int,ListBuffer[ListBuffer[Int]]] = {
vertexMap.keySet.foreach{ k =>
if(k == nodeToDelete) vertexMap.remove(k)
}
vertexMap
}
Aber es ist nur für den Punkt 1
oben erwähnt (das Entfernen des Elements mit der Taste == id_of_the_node). Plus, wenn ich es an den Scheitelpunkten von myGraph
wie folgt anrufe, gibt es mir das gewünschte Ergebnis nicht.
myGraph.vertices.map(vertex => vertex._2).map(myMap => del(3,myMap))
Wie die Methode richtig schreiben (Umsetzung sowohl Punkt 1
und 2
)? Und wie man es auf verwendet? In Pseudo-Code:
foreach key k of vertexMap
if(k == nodeToDelete) vertexMap.remove(k)
foreach ListBuffer l1
foreach ListBuffer l2
if (l2.contains(nodeTodelete)) remove the list
if(l1 is empty) vertexMap.remove(k)
Auch ist LinkedHashMap
die Datenstruktur mit der besten Zeit Komplexität für die remove
Methode?
Das Problem ist, ich weiß nicht, wie man den Zugriff auf die ListBuffer der Vertices. Sobald ich 'myGraph.vertices.map (vertexLinked => vertexLinked._2)' erstellt habe, um die LinkedHashMap zu erhalten, kann ich keine weitere Map für den Zugriff auf die Liste erstellen. Ich muss den Code, den Sie an alle Scheitelpunkte geschrieben haben, verallgemeinern, weil ich 1000 Knoten in meinem Graphen habe. – Andrea
Sehen Sie jetzt die Bearbeitung. Es funktioniert, aber durch die Art und Weise, wie die Map-Funktion eine neue Sammlung von LinkedHashMaps erstellt, wäre es perfekt, wenn ich diejenigen, die auf den Knoten existieren, direkt modifizieren könnte. – Andrea
In der funktionalen Programmierung nähern Sie sich normalerweise dem entgegengesetzten Ziel: Nicht modifizieren, was Ihnen übergeben wurde. Dadurch verhindern Sie Rennbedingungen. Die Liste der ursprünglichen Knoten in meinem Beispiel wird im Handumdrehen erstellt und ist für die Garbage Collection geeignet, sobald der Bereich verlassen wird, in dem er erstellt wurde, sodass es keine Speicherlücke geben sollte. Wenn Sie statt eines Val eine var verwenden - was meistens vermieden wird - können Sie das Ziel (die Quelle) am Ende durch das Ergebnis ersetzen. Ohne Kontext ist es schwer zu sagen, ob Sie es tun sollten und wie. –