接続された無向グラフについて考えてみましょう。エッジの整合組このグラフには、エッジように設定共有内の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つのエッジがあります。
- エッジが頂点をそれ自体に直接接続することはありません(例:エッジ
(1,1)
は入力として与えられません)。サイクルがまだ可能であることに注意してください(例:上記のグラフ)。 - 入力頂点は任意のインデックスで開始する必要があります(たとえば、最初の頂点は0、1、-1など)。
- 頂点の番号付けは、選択した開始インデックスから順番に増加します(例:
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
得点
これはコードゴルフです。最短のコードが勝ちます。標準の抜け穴が適用されます。必要なビルトインを使用できます。
[[0 1] [3 4]]
、最大値セットの代わりに失敗し[[0 2] [1 4] [3 5]]
ます。((1, 1)
間違ってそこにあると思われるエッジを無視しています)