2014-04-23 7 views
2

저는 Py2neo를 사용하고 있습니다.하지만 이것은 아마도 Cypher 쿼리를 작성하여 수행해야하기 때문에 중요하지 않습니다.특정 에지를 제외하는 최단 경로 찾기?

본질적으로 하위 그래프는 전체 그래프의 대부분이지만 제거 된 가장자리의 아주 작은 부분 (백만 분의 1 이하) 인 하위 그래프에서 최단 경로를 찾고 싶습니다.

예를 들어 노드 A, B, C 및 가장자리 (A-> B), (A-> C), (B-> C)가 있다고 가정 해보십시오. 물론 A에서 C까지의 최단 경로는 직접 연결을 통한 경로입니다. 그러나 내가 가장 짧은 경로 인 을 찾지 않으려면이 가장자리를 사용하면 AB C가되어야합니다.

또한 사용자가 다중 사용자 (웹) 환경에서 지정할 수있는 것입니다. 신청. 그래서 나는 데이터베이스 자체를 정말로 바꿀 수 없다. 문제가되지 않는다면 가장자리에 "allow : true/false"속성을 만들고 false로 설정할 수있다. 모든 현재 사용자.

"disallow : sessionID1, sessionID230, sessionID1010"의 변형이있을 것입니다. 즉, 실제로 어떤 응용 프로그램 세션이 가장자리에서 해당 가장자리를 제외 시킬지를 저장하는 것이지만 이상적으로 보이지는 않습니다.

물론 나는 실제로는 neo4j에서 필요에 따라 노드를 가져 와서 neo4j가 검색을 수행하는 대신 대기열에 보관함으로써 Python에서 BFS를 구현할 수 있지만 확실하게 훨씬 더 느려질 것입니다.

의견이 있으십니까? 감사합니다

편집 : 코드를 보려면 요청하십시오.

다음은 현재 색인에서 처음 조회하는 두 노드 사이의 최단 경로를 얻는 방법입니다. 이제 이미지에는 최단 경로 검색에서 무시해야하는 가장자리 목록 (즉, 고유 한 관계)이 있습니다.

from py2neo import neo4j 

g = neo4j.GraphDatabaseService() 

def shortest_path(a, b): 
    a = g.get_indexed_node("worddex", "word", a) 
    b = g.get_indexed_node("worddex", "word", b) 
    if not a and b: return None 
    query_string = "START beginning=node(%d), end=node(%d) MATCH p = shortestPath(beginning-[*..100]-end) RETURN p" % (a._id, b._id) 
    result = neo4j.CypherQuery(g, query_string).execute() 
    if not len(result): return None 
    p = result[0].p 
    ret = [] 
    for node in p.nodes: 
     ret.append(node["word"]) 
    return ret 

편집 2 : 예 콘솔 : http://console.neo4j.org/r/3c1rgn

하지 않는 것을 우리가 짧은 우정 경로를 찾을하려는 경우 가장 짧은 두 사람 사이에 "우정 경로"하지만, 무엇을 쉽게 찾을 수 있습니다 특정 friendshi rel (또는 특정 친목 관계의 세트)을 포함하지만 데이터베이스를 먼저 수정하지 않아도됩니까? 예를 들어, 우리는 밥에서 조까지의 가장 짧은 우정 경로를 찾고 싶습니다. 여기서 순간적으로 밥과 조는 친구가 아니며, 앨리스와 자넷도 아닙니다.

+0

코드를 알려주십시오. –

+0

약간의 질문이 있습니다. 쿼리를 만들고 Neo4 엔진을 사용하여 데이터베이스에서 데이터를 그래프 구조로 가져오고 파이썬을 사용하여 분석하는 것보다 계산을 수행하는 것이 거의 확실합니다. – EdChum

+0

@EdChum 그럴 수있다. 그래서 내 질문에, 그걸로, 어떻게 Neo4j 엔진을 사용하여 내 목표를 달성 할 수 있습니까? – user3391564

답변

2

cypher에서 'allShortestPaths'옵션을 사용할 수없고 파이썬을 사용하여 특정 rel 유형 또는 노드 유형이 포함 된 경로를 거부 할 수 없습니까? 어떻게 그리고 어떤 매개 변수를 사용하여 결과를 제한하고, 사이퍼가 경로 형태로 반환하는지 만 사용하여 탐지 할 수 있는지 여부에 달려 있다고 생각합니다.

또 다른 방법은 Cypher에게 노드에서 다른 위치로 모든 가능한 패킷을 반환하도록 지시하는 것입니다. 여기에는 일부 스마트 제한 사항이 쿼리 자체에 적용될 수 있습니다.

그런 다음 Cypher가 반환하는 경로 모음을 기반으로 특정 rel 유형이나 관심이없는 노드 유형이 포함 된 경로를 거부하는 Python 코드를 실행할 수 있습니다. 그런 다음 합격 기준에 적합한 경로 수집 (최단 조건 제외). 그런 다음 파이썬을 사용하여 경로의 길이를 계산하고 가장 작은 것을 사용할 수 있습니다.

실제로 모든 경로에 대해 Cypher 자체에서 경로 길이를 반환 할 수 있습니다. 이전에 이미 문의하셨습니다. here is the question을 참조하십시오. 그 질문에 대한 대답은 내가 말하는 것입니다.

+0

ALL POSSIBLE PATHS 옵션이 최고입니다. 그러나 가장 짧은 100 개 이상의 경로에 거부하려는 rel 또는 노드가있는 경우 성능이 상당히 저하 될 수 있습니다. neo4j가 검색 과정에서 특정 rel 또는 노드를 무시하도록 지시하는 방법이 있다면, 아마도 가능하지는 않지만 더 빠를 것 같습니다. – user3391564

+0

빠른 neo4j 콘솔을 채우고 공유 할 수 있습니까? 그건 우리가 실제로 어떤 쿼리를 실행하고 어떤 작품을 볼 수 있습니다 .. – arijeet

+0

EDIT 2 원래 게시물의 하단에 추가되었습니다. – user3391564