【问题标题】:Removing elements from LinkedHashMap and ListBuffer of ListBuffer, used as vertex attributes into a graph structure从 ListBuffer 的 LinkedHashMap 和 ListBuffer 中删除元素,用作顶点属性到图结构中
【发布时间】:2017-12-30 22:15:04
【问题描述】:

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

  • key:节点的id - 如Int
  • 值:到达节点的所有可能路径 - 每条路径都是ListBuffer[Int],所以我有ListBufferListBuffer[Int]

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

  1. 在每个 LinkedHashMap 中删除键 == id_of_the_node 的元素
  2. 删除每个ListBuffer[ListBuffer[Int]] 中包含已删除节点的列表(路径)(路径将不再存在)。

假设我有以下节点(我将省略其他节点):

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

假设我想从myGraph 中删除节点3。那么,节点的属性应该变成:

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

另外,LinkedHashMapremove 方法时间复杂度最高的数据结构吗?

【问题讨论】:

    标签: scala linkedhashmap spark-graphx listbuffer


    【解决方案1】:

    由于我没有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()
    

    lbuter 和 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))))
    

    【讨论】:

    • 问题是,我不知道如何访问顶点的ListBuffers。一旦我完成了myGraph.vertices.map(vertexLinked => vertexLinked._2) 以获取 LinkedHashMap,我就不能再做一个地图来访问该列表。我必须将您编写的代码推广到所有顶点,因为我的图中有 1000 个节点。
    • 现在看到编辑。它可以工作,但是通过 map 函数创建一个新的 LinkedHashMap 集合的方式,如果我可以直接修改节点上存在的那些,那将是完美的。
    • 在函数式编程中,您通常会达到相反的目标:不要修改已传递给您的内容。从而防止竞争条件。我的示例中的原始节点列表是动态创建的,并且有资格进行垃圾收集,只要范围离开,它是在哪里构造的,所以不应该有内存漏洞。如果您碰巧使用 var 而不是 val - 大多数情况下不鼓励这样做,您可以在最后用结果替换它的目标(源)。没有上下文,很难判断您是否应该这样做以及如何做。
    • 上下文:我的图包含在一个社交网络上,其中节点是用户,边是他们之间的关系。 (1) 我需要知道哪个用户与另一个用户相关联,这就是哈希映射的原因。 (2) 社交网络是动态的,我希望图表反映这个属性,这就是为什么我要删除一个节点(对应于用户删除其帐户)。 (3) 删除一个节点等于在每个哈希映射中删除它。
    • 嗯,我更多地考虑了编程术语中的上下文,但这在 SE 上肯定是太多了。
    猜你喜欢
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多