最大一致エッジのセットを見つける


13

接続された無向グラフについて考えてみましょう。エッジの整合組このグラフには、エッジように設定共有内の2つのエッジが共通の頂点の集合として定義されます。たとえば、左の図は一致するセットを緑で示し、右の図は一致しないセットを赤で示します。

ここに画像の説明を入力してください

一致するセットはと呼ばれます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、関数パラメーターなど)からグラフを取得する必要があります。追加の重要な情報がプログラムに伝達されない限り、任意の表記を使用できます。たとえば、入力エッジの数を示す追加のパラメーターを使用することは完全に受け入れられます。同様に、エッジの順序なしマルチセット、隣接リスト、または隣接行列を渡すことは問題ありません。

あなたは仮定するかもしれません:

  1. グラフは接続されています(たとえば、開始頂点があれば、どの頂点にも到達できます)。
  2. 少なくとも1つのエッジがあります。
  3. エッジが頂点をそれ自体に直接接続することはありません(例:エッジ(1,1)は入力として与えられません)。サイクルがまだ可能であることに注意してください(例:上記のグラフ)。
  4. 入力頂点は任意のインデックスで開始する必要があります(たとえば、最初の頂点は0、1、-1など)。
  5. 頂点の番号付けは、選択した開始インデックスから順番に増加します(例:1,2,3,4,...、または0,1,2,3,...)。

出力

プログラム/関数は、最大一致セットを示すエッジのリストを出力する必要があります。エッジは、そのエッジが接続する2つの頂点によって定義されます。例 左の青いセットの出力(入力頂点の順序の例を使用):

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

頂点の順序は重要ではないことに注意してください。したがって、次の出力は同じ一致セットを示しています。

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

出力は、標準出力、ファイル、関数の戻り値などになります。

次に、いくつかの入力例を示します(隣接リスト形式を使用)。これらの例では、で頂点のカウントを開始してい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/}

オンラインデモ

これは、以前に蓄積されたエッジと共通の頂点を持たないエッジを蓄積する貪欲なアプローチです。


これは3番目の例で失敗し[[0 1] [3 4]]、最大値セットの代わりに失敗し[[0 2] [1 4] [3 5]]ます。((1, 1)間違ってそこにあると思われるエッジを無視しています)
-ETHproductions

@ETHproductions、あなたは最大と最大を混同しています。
ピーターテイラー

3
これは定期的な発行:-Pのようですので、Dangitは、申し訳ありませんそれについて...私は、あなたが気にしない場合は、混乱しているすべての人を助けるために私のコメントを残しておきます
ETHproductions

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

Wolfram言語、25 22バイト

@MartinEnderのおかげで3バイト節約

FindIndependentEdgeSet

これは入力をGraphオブジェクトとして受け取ります(Graph[{1<->2,2<->3,1<-3>}]などとして定義されます)


あなたは必要ありません@#&
マーティンエンダー

@MartinEnderありがとう。
スコットミルナー

Pfft。import solve_problem; run()。さて、誰かがcodegolfチャレンジ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は最大のサブセットから検索するため、これが最大になることが保証されます。


あなたの説明には実際のコードとは異なるコードがあると思います。
エリックアウトゴルファー

@EriktheOutgolferこれは、説明に暗黙的な文字を挿入したためです。元のコードは最初の行にあります。Brachylogはこの点で非常に簡潔です。
リーキー修道女

というわけではありませんが、最初のコードはで終わり≠∧、2番目のコードはで終わりL≠ます。
エリックアウトゴルファー

がなければ.最後に暗黙的なものがあります。ここでのすべての手段は.、最後にを挿入しないことです。
リーキー修道女

Lしたがって、その能力が省略されるように、どこにも使用されていない一時的な変数です。
リーキー修道女

0

JavaScript(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

JavaScript(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.