从LinkedBasher的LinkedHashMap和ListBuffer中删除元素,将其用作顶点属性到图形结构中

时间:2017-12-30 22:15:05

标签: scala linkedhashmap spark-graphx listbuffer

我使用GraphX API在Scala中构建了一个图形。在我的图表中,每个顶点都有一个LinkedHashMap[Int, ListBuffer[ListBuffer[Int]]]属性:LinkedHashMap的每对(键,值)代表:

  • key:节点的ID - Int
  • value:到达节点的所有可能路径 - 每条路径都是ListBuffer[Int],因此我有ListBuffer ListBuffer[Int]

(我已使用Pregel创建LinkedHashMap s。 所以,我想实现从图中删除节点的情况。我要做的是:

  1. 在每个LinkedHashMap中删除带有键的元素== id_of_the_node
  2. 在每个ListBuffer[ListBuffer[Int]]中删除包含已删除节点的列表(路径)(该路径将不再存在)。
  3. 假设我有以下节点(我将省略其他节点):

    节点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))))

    节点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))))

    节点3:(3,Map(5 -> ListBuffer(ListBuffer(3, 5)), 6 -> ListBuffer(ListBuffer(3, 6)), 3 -> ListBuffer(ListBuffer(3))))

    假设我想从3删除节点myGraph。然后,节点的属性应该变为:

    节点1:(1, Map(5 -> ListBuffer(ListBuffer(1, 4, 5)), 4 -> ListBuffer(ListBuffer(1, 4)), 1 -> ListBuffer(ListBuffer(1))))

    节点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))))

    节点3:(-1, LinkedHashMap[ListBuffer[ListBuffer[]]]()) - 我不知道如何分配空的LinkedHashMap[ListBuffer[ListBuffer[Int]]]

    我已经定义了以下方法:

    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
        }
    

    但它仅适用于上面提到的1点(使用键== id_of_the_node删除元素)。另外,如果我在myGraph的顶点上调用它,如下所示,它不会给我想要的结果。

    myGraph.vertices.map(vertex => vertex._2).map(myMap => del(3,myMap))
    

    如何正确编写方法(实现点12)?以及如何在myGraph.vertices上使用它?在伪代码中:

    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)
    

    另外,LinkedHashMap方法的remove数据结构是否具有最佳时间复杂度?

1 个答案:

答案 0 :(得分:0)

由于我没有使用GraphX Api,我使用了你的代码,我希望紧密相关,定义如下:

val node1 = (1, Map(5 -> ListBuffer(ListBuffer(1, 4, 5)), 4 -> ListBuffer(ListBuffer(1, 4)), 1 -> ListBuffer(ListBuffer(1))))

等对于node2和3,它只是通过导入ListBuffer在REPL中工作。然后我可以通过过滤删除:

node1._2.map (_._2.filter (! _.contains (3))).filter (_.size > 0)
/*
res34: scala.collection.immutable.Iterable[scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[Int]]] = 
List(ListBuffer(ListBuffer(1, 4, 5)), 
  ListBuffer(ListBuffer(1)), ListBuffer(ListBuffer(1, 4)))
*/    
scala> node2._2.map (_._2.filter (! _.contains (3))).filter (_.size > 0)
    /*
    res35: scala.collection.immutable.Iterable[scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[Int]]] =
 List(
  ListBuffer(ListBuffer(2, 1, 4, 5)), ListBuffer(ListBuffer(2, 1)), 
  ListBuffer(ListBuffer(2)), ListBuffer(ListBuffer(2, 1, 4)))
    */

node3._2.map (lbouter => lbouter._2.filter (lbinner=> ! lbinner.contains (3))).filter (_.size > 0)
res36: scala.collection.immutable.Iterable[scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[Int]]] = List()

lbouter和lbinner代表内部和外部ListBuffers。

更新:具有删除功能的可执行示例:

import collection.mutable._

def delnode (x: Int, vertexMap: Map [Int, ListBuffer [ListBuffer [Int]]]) = {
    vertexMap.values.map (_.filter (! _.contains (x))).filter (_.size > 0)
}

val anode = (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))))
val bnode = (Map (5 -> ListBuffer (ListBuffer (2, 1, 3, 5), ListBuffer (2, 1, 4, 5)), 1 -> ListBuffer(ListBuffer (2, 1)), 6 -> ListBuffer(ListBuffer (2, 1, 3, 6)), 2 -> ListBuffer(ListBuffer (2)), 3 -> ListBuffer(ListBuffer (2, 1, 3)), 4 -> ListBuffer(ListBuffer (2, 1, 4))))
val cnode = (Map (5 -> ListBuffer (ListBuffer (3, 5)), 6 -> ListBuffer(ListBuffer (3, 6)), 3 -> ListBuffer(ListBuffer (3))))

delnode (3, bnode) 
/* 
res9:  Iterable[scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[Int]]] = 
List(
ListBuffer(ListBuffer(2)), ListBuffer(ListBuffer(2, 1, 4, 5)),
ListBuffer(ListBuffer(2, 1, 4)), ListBuffer(ListBuffer(2, 1)))

对于多个节点,映射它们并删除空结果:

    List (anode, bnode, cnode).map (n => delnode (3, n)).filter (_.size > 0) 
res12: List[Iterable[scala.collection.mutable.ListBuffer[scala.collection.mutable.ListBuffer[Int]]]] = List(List(ListBuffer(ListBuffer(1, 4, 5)), ListBuffer(ListBuffer(1, 4)), ListBuffer(ListBuffer(1))), List(ListBuffer(ListBuffer(2)), ListBuffer(ListBuffer(2, 1, 4, 5)), ListBuffer(ListBuffer(2, 1, 4)), ListBuffer(ListBuffer(2, 1))))