무 방향 그래프 의 트리 폭 은 그래프 이론에서 매우 중요한 개념입니다. 트리 폭이 작은 그래프를 분해하면 빠르게 실행되는 수많은 그래프 알고리즘이 발명되었습니다.
트리 폭은 종종 트리 분해로 정의됩니다. 다음은 Wikipedia에서 제공 한 그래프와 그 그래프의 트리 분해입니다.
트리 분해는 다음과 같은 속성을 사용하여 각 정점이 원래 그래프의 정점의 하위 집합과 연결되는 트리입니다.
- 원본 그래프의 모든 정점은 하나 이상의 하위 집합에 있습니다.
- 원본 그래프의 모든 모서리에는 하나 이상의 하위 집합에 정점이 모두 있습니다.
- 주어진 원본 정점이 포함 된 부분 집합이있는 분해의 모든 정점이 연결됩니다.
위의 분해가이 규칙을 따르는 지 확인할 수 있습니다. 트리 분해의 너비는 가장 큰 부분 집합의 크기에서 1을 뺀 크기입니다. 따라서, 상기 분해의 경우 2 개이다. 그래프의 트리 폭은 해당 그래프의 트리 분해에서 가장 작은 폭입니다.
이 도전에서, 당신은 연결된 무 방향 그래프를 받게 될 것이고, 당신은 그것의 treewidth를 찾아야합니다.
트리 분해를 찾기는 어렵지만 트리 폭을 계산하는 다른 방법이 있습니다. Wikipedia 페이지에는 더 많은 정보가 있지만 트리 폭을 계산하기 위해 알고리즘에서 자주 사용되는 트리 폭을 계산하는 한 가지 방법은 최소 제거 순서 폭입니다. 이 사실을 사용한 논문 은 여기 를 참조 하십시오 .
제거 순서에서 한 번에 하나씩 그래프의 모든 정점을 제거합니다. 각 정점이 제거되면 해당 정점의 모든 이웃을 서로 연결하는 가장자리가 추가됩니다. 모든 정점이 사라질 때까지이 과정이 반복됩니다. 제거 순서 폭은 제거되는 정점이이 프로세스 동안 갖는 최대 이웃 수입니다. 트리 폭은 모든 제거 순서 폭의 순서에 대한 최소값과 같습니다. 다음은이 사실을 사용하여 트리 폭을 계산하는 예제 프로그램입니다.
import itertools
def elimination_width(graph):
max_neighbors = 0
for i in sorted(set(itertools.chain.from_iterable(graph))):
neighbors = set([a for (a, b) in graph if b == i] + [b for (a, b) in graph if a == i])
max_neighbors = max(len(neighbors), max_neighbors)
graph = [edge for edge in graph if i not in edge] + [(a, b) for a in neighbors for b in neighbors if a < b]
return max_neighbors
def treewidth(graph):
vertices = list(set(itertools.chain.from_iterable(graph)))
min_width = len(vertices)
for permutation in itertools.permutations(vertices):
new_graph = [(permutation[vertices.index(a)], permutation[vertices.index(b)]) for (a, b) in graph]
min_width = min(elimination_width(new_graph), min_width)
return min_width
if __name__ == '__main__':
graph = [('a', 'b'), ('a', 'c'), ('b', 'c'), ('b', 'e'), ('b', 'f'), ('b', 'g'),
('c', 'd'), ('c', 'e'), ('d', 'e'), ('e', 'g'), ('e', 'h'), ('f', 'g'), ('g', 'h')]
print(treewidth(graph))
예 :
[(0, 1), (0, 2), (0, 3), (2, 4), (3, 5)]
1
[(0, 1), (0, 2), (1, 2), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (3, 4), (4, 6), (4, 7), (5, 6), (6, 7)]
2
[(0, 1), (0, 3), (1, 2), (1, 4), (2, 5), (3, 4), (3, 6), (4, 5), (4, 7), (5, 8), (6, 7), (7, 8)]
3
[(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
4
그래프를 입력으로 받고 트리 폭을 출력으로 반환해야합니다. 입력 형식이 유연합니다. 모서리 목록, 인접 맵 또는 인접 행렬을 입력으로 사용할 수 있습니다. 다른 입력 형식을 사용하려면 의견을 요청하십시오. 입력이 연결되어 있다고 가정 할 수 있으며 예를 들어 모서리 목록을 사용하여 입력 형식으로 해당 가정을 구축 할 수 있습니다.
편집 : 트리 폭을 계산하는 내장 작업은 허용되지 않습니다. 이것을 미리 지정하지 않은 것에 대해 사과드립니다.
가장 짧은 코드가 승리합니다.
(V,E)
이것이 유효한 입력입니까?