2017-12-30 10 views
1

GraphX ​​API를 사용하여 스칼라에 그래프를 작성했습니다. 가능한 모든 경로에 도달 : - 대표 각 한 쌍 (키, 값)이 LinkedHashMap의 : : :ListBuffer의 LinkedHashMap 및 ListBuffer에서 요소를 제거하여 그래프 구조에 정점 속성으로 사용

  • Int
  • 값으로 노드의 ID를 내 그래프에서 각 정점은 LinkedHashMap[Int, ListBuffer[ListBuffer[Int]]] 특성으로있다 노드 - 모든 경로는 ListBuffer[Int], 그래서 나는이 ListBuffer

ListBuffer[Int]의 (나는 LinkedHashMap의를 만들 Pregel을 사용했습니다)이있다. 그래서 그래프에서 노드를 제거하는 경우를 구현하고 싶습니다. 내가해야 할 것은 각 ListBuffer[ListBuffer[Int]]의 각 LinkedHashMap에서 제거

  1. , 키 == id_of_the_node
  2. 제거와 요소, 목록 삭제 된 노드를 포함 (경로) (경로 것 더 이상 존재하지 않는다).

가정하자 나는 다음 노드 (나는 다른 사람을 생략합니다)이 :

노드 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))))

그리고 가정을 노드 3myGraph에서 삭제하고 싶습니다. 그런 다음, 노드의 속성이되어야 :

노드 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 
    } 

을하지만 그것은 단지 (키 == id_of_the_node으로 요소를 제거) 위에서 언급 한 점 1을 위해입니다. 게다가 다음과 같이 verticle of 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 방법에 가장 적합한 시간 복잡도와 데이터 구조?에서 근무 노드 2, 3, 위해 등

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

과 : 나는 GraphX ​​API를 가지고 있지 않기 때문에

답변

0

, 난 단단히 같이, 정의를 관련 희망, 일부 코드를 사용 REPL 그냥 ListBuffer 가져 오기. 그런 다음 필터링을 통해 제거 할 수 있습니다.

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는 내부 및 외부 ListBuffer를 나타냅니다.

업데이트 : 여러 노드에 대한

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)))) 
+0

문제는, 난에 액세스하는 방법을 모른다 정점의 ListBuffer LinkedHashMap을 얻기 위해'myGraph.vertices.map (vertexLinked => vertexLinked._2) '를 실행하면 목록에 액세스 할 수있는 다른지도를 작성할 수 없습니다. 그래프에 1000 개의 노드가 있기 때문에 모든 정점에 작성한 코드를 일반화해야합니다. – Andrea

+0

편집보기. 그것은 작동하지만 map 함수가 LinkedHashMaps의 새로운 콜렉션을 생성하는 방식으로, 노드에 직접 존재하는 것을 직접 수정할 수 있다면 완벽 할 것입니다. – Andrea

+0

함수형 프로그래밍에서는 대개 반대 목표 인 : 수정하지 말고 전달 된 내용에 접근합니다. 따라서 경쟁 조건을 방지 할 수 있습니다. 예제의 원래 노드 목록은 범위가 남아있는 즉시 즉석에서 만들어지고 가비지 수집 대상이되므로 메모리 구멍이 없어야합니다. val 대신 var를 사용하면 대부분의 시간이 낙심하기 때문에 결국 대상 (소스)을 결과로 바꿀 수 있습니다. 문맥이 없으면, 당신이 그것을해야하는지, 어떻게해야 하는지를 말하기 어렵습니다. –

관련 문제