최대 매칭 모서리 세트 찾기


13

연결된 무 방향 그래프를 고려하십시오. 에지 정합 집합 이 그래프에서 에지가되도록 설정된 주에있는 두 개의 에지가 공통 정점의 집합으로 정의된다. 예를 들어 왼쪽 그림은 녹색으로 일치하는 집합을 나타내고 오른쪽 그림은 비 일치 집합을 빨간색으로 나타냅니다.

여기에 이미지 설명을 입력하십시오

일치 집합은이라고하며 maximally matching, maximal matching일치하는 집합에 그래프의 다른 가장자리를 추가 할 수없는 경우입니다. 따라서 위의 두 예제는 모두 최대 일치 세트가 아니지만 아래의 파란색 세트는 모두 최대 일치입니다. 최대 일치는 반드시 고유하지는 않습니다. 또한, 그래프에 대해 가능한 최대 매칭의 크기가 다른 매칭과 동일 할 필요는 없습니다.여기에 이미지 설명을 입력하십시오

이 과제의 목표는 프로그램 / 함수를 작성하여 그래프의 최대 매칭을 찾는 것입니다.

입력

입력 그래프의 모든 정점에 선택한 시작 정수 값에서 시작하는 연속적인 정수 번호가 있다고 가정합니다. 에지는 에지가 연결하는 정점을 나타내는 정렬되지 않은 정수 쌍으로 설명됩니다. 예를 들어, 위에 표시된 그래프는 다음과 같이 정렬되지 않은 다음 모서리 세트로 설명 될 수 있습니다 (정점의 번호가 0에서 시작한다고 가정).

[(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]

그래프를 설명하는 다른 방법은 인접 목록을 사용하는 것입니다. 위의 그래프에 대한 예제 인접 목록은 다음과 같습니다.

[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]

프로그램 / 기능은 소스 (stdio, function parameter 등)에서 그래프를 입력으로 가져와야합니다. 사소한 추가 정보가 프로그램에 전달되지 않는 한 원하는 표기법을 사용할 수 있습니다. 예를 들어, 입력 에지 수를 나타내는 추가 매개 변수를 갖는 것은 완벽하게 허용됩니다. 마찬가지로 정렬되지 않은 여러 가장자리 세트, 인접 목록 또는 인접 행렬을 전달하는 것이 좋습니다.

당신은 가정 할 수 있습니다 :

  1. 그래프가 연결됩니다 (예 : 시작 정점이 주어지면 정점에 도달 할 수 있음).
  2. 가장자리가 하나 이상 있습니다.
  3. 가장자리는 절대 꼭짓점을 직접 연결하지 않습니다 (예 : 가장자리 (1,1)는 입력으로 제공되지 않습니다). 사이클은 여전히 ​​가능합니다 (예 : 위의 그래프).
  4. 입력 정점은 모든 인덱스에서 시작해야 할 수 있습니다 (예 : 첫 번째 정점은 0, 1, -1 등일 수 있음).
  5. 정점 번호는 선택한 시작 색인 (예 : 1,2,3,4,..., 또는 0,1,2,3,...) 에서 순차적으로 증가하고 있습니다 .

산출

프로그램 / 기능은 최대 일치 세트를 나타내는 모서리 목록을 출력해야합니다. 모서리는 해당 모서리가 연결되는 두 정점으로 정의됩니다. 전의. 왼쪽 파란색 세트에 대한 출력 (입력 정점 순서 예제 사용) :

[(1,4), (2,3), (5,6)]

꼭짓점의 순서는 중요하지 않습니다. 따라서 다음 출력은 동일한 일치 세트를 설명합니다.

[(4,1), (2,3), (6,5)]   

출력은 stdout, 파일, 함수 반환 값 등이 될 수 있습니다.

다음은 입력 목록의 예입니다 (인접 목록 형식 사용). 이 예제는에서 정점 계산을 시작합니다 0.

예제 출력은 제공되지 않으며 대신 Python 3 유효성 검사 코드를 포함 시켰습니다.

[0:(1), 1:(0)]

[0:(1,2), 1:(0,3,4), 2:(0,3), 3:(1,2,4,5), 4:(1,3), 5:(3,6), 6:(5)]

[0:(1,2), 1:(0,2,3,4,5), 2:(0,1), 3:(1), 4:(1), 5:(1)]

[0:(1,2), 1:(0,2,3), 2:(0,1,4), 3:(1,4,5), 4:(2,3), 5:(3)]

유효성 검사 Python 3 코드

다음은 그래프와 가장자리 집합을 가져 와서 해당 집합이 최대 일치하는지 여부를 인쇄하는 Python 3 유효성 검사 코드입니다. 이 코드는 모든 버텍스 시작 인덱스와 함께 작동합니다.

def is_maximal_matching(graph, edges):
    '''
    Determines if the given set of edges is a maximal matching of graph
    @param graph a graph specified in adjacency list format
    @param edges a list of edges specified as vertex pairs

    @return True if edges describes a maximal matching, False otherwise.
    Prints out some diagnostic text for why edges is not a maximal matching
    '''

    graph_vtxs = {k for k,v in graph.items()}
    vtxs = {k for k,v in graph.items()}

    # check that all vertices are valid and not used multiple times
    for e in edges:
        if(e[0] in graph_vtxs):
            if(e[0] in vtxs):
                vtxs.remove(e[0])
            else:
                print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[0]))
                return False
        else:
            print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
            return False
        if(e[1] in graph_vtxs):
            if(e[1] in vtxs):
                vtxs.remove(e[1])
            else:
                print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[1]))
                return False
        else:
            print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
            return False
        if(e[1] not in graph[e[0]]):
            print('edge (%d,%d): edge not in graph'%(e[0],e[1]))
            return False

    # check that any edges can't be added
    for v in vtxs:
        ovtxs = graph[v]
        for ov in ovtxs:
            if(ov in vtxs):
                print('could add edge (%d,%d) to maximal set'%(v,ov))
                return False

    return True

사용법 예 :

graph = {0:[1,2], 1:[0,3,4], 2:[0,3], 3:[1,2,4,5], 4:[1,3], 5:[3,6], 6:[5]}
candidate = [(0,1),(2,3)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6),(0,1)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6)]
is_maximal_matching(graph, candidate) // True

채점

이것은 코드 골프입니다. 가장 짧은 코드가 승리합니다. 표준 허점이 적용됩니다. 원하는 내장 기능을 사용할 수 있습니다.

답변:


9

CJam (16 자)

{M\{_2$&!*+}/2/}

온라인 데모

이는 이전에 누적 된 모서리와 공통 인 꼭지점이없는 모서리를 누적하는 욕심스러운 접근 방식입니다.


나는 이것이 [[0 1] [3 4]]최대 세트 대신에 세 번째 예제에서 실패한다고 확신합니다 [[0 2] [1 4] [3 5]]. ( (1, 1)실수로
우연히

@ETHproductions, 당신은 최대와 최대를 혼동하고 있습니다.
피터 테일러

3
Dangit, 죄송합니다. 반복되는 문제인 것 같습니다. 걱정하지
않으시면

7

Pyth , 8 바이트

ef{IsTty
       y  power set (gerenate all set of edges)
      t   remove the first one (the first one is
          empty and will cause problems)
 f        filter for sets T satisfying:
     T        T
    s         flatten
  {I          is invariant under deduplicate, i.e. contains no
              duplicating vertices, as the elements represent vertices
e         pick the last one (the power set is ordered from
          smallest to largest)

온라인으로 사용해보십시오!

명세서

  • 입력: [(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
  • 산출: [(1, 4), (2, 3), (5, 6)]

6

볼프람 언어, 25 22 바이트

@MartinEnder 덕분에 3 바이트 절약

FindIndependentEdgeSet

이것은 같은 입력을 얻어 Graph개체 (정의 Graph[{1<->2,2<->3,1<-3>}]등)


필요하지 않습니다 @#&.
Martin Ender

@MartinEnder 감사합니다.
Scott Milner

ff import solve_problem; run(). 이제 누군가 골퍼 챌린지 URL을 가져와 원하는 출력을 출력하는 Wolfram 용 플러그인을 작성하면됩니다. 를 호출합니다 Golf.
Draco18s는 더 이상 SE

5

Brachylog , 5 바이트

 ⊇.c≠∧

?⊇.cL≠   implicit ? at the beginning;
         ∧ breaks implicit . at the end;
         temporary variable inserted.
?⊇.      input is a superset of output
  .cL    output concatenated is L
    L≠   L contains distinct elements

온라인으로 사용해보십시오!

Brachylog가 가장 큰 하위 집합을 검색하기 때문에 최대 값을 보장합니다.


귀하의 설명이 실제 코드와 다른 코드라고 생각합니다.
Outgolfer Erik

@EriktheOutgolfer 설명에 암시적인 문자를 삽입했기 때문입니다. 원래 코드는 첫 번째 줄에 있습니다. Brachylog는이 측면에서 매우 간결합니다.
Leaky Nun

나는 그것을 의미하지는 않지만 첫 번째 코드는로 ≠∧끝나고 두 번째 코드는로 끝납니다 L≠.
Outgolfer Erik

이 없으면 마지막에 암시 적 .으로 나타납니다. 여기서 모든 .것은 끝에 삽입하지 않아야한다는 것입니다.
Leaky Nun

L따라서 그 기능을 생략하는데도 사용되지 임시 변수이다.
Leaky Nun

0

자바 스크립트 (ES6), 67 바이트

let f =
a=>a.map(b=>r.some(c=>c.some(d=>~b.indexOf(d)))||r.push(b),r=[])&&r

let g = a => console.log("[%s]", f(a).map(x => "[" + x + "]").join(", "))
g([[0,1]])
g([[0,1], [0,2], [1,3], [1,4], [2,3], [3,4], [3,5], [5,6]])
g([[0,1], [0,2], [1,2], [1,3], [1,4], [1,5]])
g([[0,1], [0,2], [1,2], [1,3], [2,4], [3,4], [3,5]])

욕심 많은 접근 방식을 사용하여 최대한의 골프를 즐기십시오.


0

자바 스크립트 (ES6), 68 66 바이트

f=a=>a[0]?[a[0],...f(a.filter(b=>!a[0].some(c=>~b.indexOf(c))))]:a
f=([b,...a])=>b?[b,...f(a.filter(c=>!c.some(c=>~b.indexOf(c))))]:a

나는 재귀 접근 방식을 사용하겠다고 생각하고 @ETHproduction의 설정된 교차 트릭을 훔쳐서 그의 대답을 깎을 수있었습니다!

나는 원래의 질문을 처음 읽지 않았으며, 최대 매칭 에지 세트가 아닌 최대 매칭 에지 세트를 찾는 다음 재귀 함수를 제출하려고했습니다. 미묘한 차이, 알아요!

f=a=>a.map(([b,c])=>[[b,c],...f(a.filter(([d,e])=>b-d&&b-e&&c-d&&c-e))]).sort((d,e)=>e.length-d.length)[0]||[]

간단한 재귀 접근. 각 입력 요소에 대해 세트에서 충돌하는 모든 모서리를 삭제하고 나머지 서브 세트의 최대 일치하는 모서리 세트를 찾은 다음 각 입력 요소에서 최대 결과를 찾습니다. 큰 세트에는 다소 비효율적입니다 (9 바이트 속도 향상 가능).


0

젤리 , 12 11 바이트

FQ⁼F
ŒPÇÐfṪ

온라인으로 사용해보십시오!

샘플 입력 : [0,1],[0,2],[1,3],[1,4],[2,3],[3,4],[3,5],[5,6]

샘플 출력 : [[1, 4], [2, 3], [5, 6]]

작동 원리

FQ⁼F    - Helper function, returns 1 if a set of edges is non-matching
F       - Flatten input
 Q      - Remove repeated elements
  ⁼     - Return boolean value. Is this equal to
   F    - The flattened input list

ŒPÇÐfṪ - Main link.
ŒP     - Power set of input list of edges
   Ðf  - Remove all elements which return 1 if
  Ç    - (Helper function) it is a non-matching set
     Ṫ - Get the last element in the resultant list (the longest). 
           Always maximal because it is the longest, so any
           edge added would not be in this list (not matching)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.