[コンセプト]10.グラフィック理論
23960 ワード
リンクテキスト
データ構造 まで、集合資料構造は2つの演算をサポートしませんでした. とセット(Union):2つの要素を含むセットを1つのセットに統合する演算 検索(Find):エレメントが属する集合が何であるかを示す演算
集合データ構造は、連合検索データ構造 と呼ばれる.
の複数の連結演算が与えられると、集合資料構造の動作過程は以下の通りである: の集合演算を確認し、2つの相互接続ノードA,Bを確認する
a.AとBのルートノードA’,B’をそれぞれ探す
b.A′をB′に設定親ノード プロセス は、すべての並列セット(Union)演算が処理されるまで繰り返される.
パス圧縮最適化を使用して関数を検索できます. ルックアップ(Find)関数を再呼び出し、親テーブル値 をすぐに更新します.パス圧縮技術を用いて、各ノードに対してルックアップ(Find)関数を呼び出すと、そのノードのルートノードは親ノード となる.
同じ例に対してすべてのUnion関数を処理し、各要素に対してFind関数を実行すると、親テーブルは更新されます: 基本法と比較して,時間的複雑度は 向上した.
図にはすべてのノードが含まれており、ループが存在しないことを示す部分図 を含むすべてのノードは、互いに接続するループが存在しない条件もツリーの条件 である.
最もコストの低い拡張ツリーを探す必要がある場合はどうすればいいですか? 例えばは、N都市が存在すると仮定し、2つの都市の間に道路を設け、都市全体を相互に接続する の2都市A,Bが選択すると、A~Bの経路が存在することを確保するために、道路 が設けられる.
の代表的な最小伸長ツリーアルゴリズム 階調アルゴリズム に分類する具体的な動作過程は以下の通りである: 1)幹線データを料金の昇順に並べる
2)幹線を1本ずつ点検し、現在の幹線に周期が発生しているか確認するサイクルが発生しない場合、最小伸長ツリーに含まれる .サイクルが発生する場合、最小伸長ツリーに含まれない .
3)すべての幹線に対して2回の過程を繰り返す
クルースカルアルゴリズムは、幹線数がEの場合、O(logE)の時間的複雑度 を有する.クルースカアルゴリズムで最も要求時間が多いのは、幹線ソートを実行する部分 である.標準ライブラリの使用𝐸データの並べ替えの時間的複雑度はO(ElogE) である.
サイクルのない方向図のすべてのノードを順番にリストして、方向性に違反しないようにします.
例)選手科目の学習順序 を設定する.
以上の3つの授業の適当な学習順序は?
データ構造→アルゴリズム→高度アルゴリズム(O)
データ構造→高度アルゴリズム→アルゴリズム(X)
キューの位相整列アルゴリズムを使用する動作手順は、次のとおりです.
1)アクセス数0のすべてのノードをキューに入れる
2)Q要求まで次の手順を繰り返す a)キューから要素を取り出し、ノード上の幹線をグラフから 削除する. b)新たな入力差が0のノードをキュー に入れる.
=>結果は、各ノードがキューに入る順序が位相ソートを実行した結果と同じです.
位相較正はDAGのみ 直結ループパターン:非ループ方向図 位相キャリブレーションでは、複数の答えが存在する可能性がある フェーズでは、キューに2つ以上の新しい要素がある場合、複数の答えが存在します.
すべての要素にアクセスする前に、キューが空の場合、ループがあると判断できます.サイクルに含まれる要素のうち、どの要素もキュー に入ることができない.
スタックを有するDFSを用いて位相整合を行うこともできる
位相をソートするには、すべてのノードを順次チェックし、各ノードの配線を順次削除する必要がある. 位相並べ替えアルゴリズムの時間的複雑度はO(V+E) である.
集合データ構造
集合データ構造は、連合検索データ構造
a.AとBのルートノードA’,B’をそれぞれ探す
b.A′をB′に設定親ノード
集約リソース構造:基本的な実装方法(Python)
# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
# 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
if parent[x] != x:
return find_parent(parent, parent[x])
return x
# 두 원소가 속한 집합을 합치기
def union_parent(parent, a, b):
a = find_parent(parent, a)
b = find_parent(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
# 노드의 개수와 간선(Union 연산)의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) # 부모 테이블 초기화하기
# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
parent[i] = i
# Union 연산을 각각 수행
for i in range(e):
a, b = map(int, input().split())
union_parent(parent, a, b)
# 각 원소가 속한 집합 출력하기
print('각 원소가 속한 집합: ', end='')
for i in range(1, v + 1):
print(find_parent(parent, i), end=' ')
print()
# 부모 테이블 내용 출력하기
print('부모 테이블: ', end='')
for i in range(1, v + 1):
print(parent[i], end=' ')
集合データ構造のみ集合データこうぞう:パス圧縮パスあっしゅく
パス圧縮最適化
# 특정한 원소가 속한 집합을 찾기
def find_parent(parent, x):
# 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
同じ例
腎臓の木
さいしょうのびじゅ
クルーズアルゴリズム
2)幹線を1本ずつ点検し、現在の幹線に周期が発生しているか確認する
3)すべての幹線に対して2回の過程を繰り返す
クルーズアルゴリズム性能分析
クルーズアルゴリズム(Python)
# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
# 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
# 두 원소가 속한 집합을 합치기
def union_parent(parent, a, b):
a = find_parent(parent, a)
b = find_parent(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
# 노드의 개수와 간선(Union 연산)의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) # 부모 테이블 초기화하기
# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수
edges = []
result = 0
# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
parent[i] = i
# 모든 간선에 대한 정보를 입력 받기
for _ in range(e):
a, b, cost = map(int, input().split())
# 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정
edges.append((cost, a, b))
# 간선을 비용순으로 정렬
edges.sort()
# 간선을 하나씩 확인하며
for edge in edges:
cost, a, b = edge
# 사이클이 발생하지 않는 경우에만 집합에 포함
if find_parent(parent, a) != find_parent(parent, b):
union_parent(parent, a, b)
result += cost
print(result)
位相位置合わせ
例)選手科目の学習順序
以上の3つの授業の適当な学習順序は?
データ構造→アルゴリズム→高度アルゴリズム(O)
データ構造→高度アルゴリズム→アルゴリズム(X)
フェーズアライメントアルゴリズム
キューの位相整列アルゴリズムを使用する動作手順は、次のとおりです.
1)アクセス数0のすべてのノードをキューに入れる
2)Q要求まで次の手順を繰り返す
=>結果は、各ノードがキューに入る順序が位相ソートを実行した結果と同じです.
位相整列フィーチャー
フェーズアライメントアルゴリズムのパフォーマンス分析
from collections import deque
# 노드의 개수와 간선의 개수를 입력 받기
v, e = map(int, input().split())
# 모든 노드에 대한 진입차수는 0으로 초기화
indegree = [0] * (v + 1)
# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화
graph = [[] for i in range(v + 1)]
# 방향 그래프의 모든 간선 정보를 입력 받기
for _ in range(e):
a, b = map(int, input().split())
graph[a].append(b) # 정점 A에서 B로 이동 가능
# 진입 차수를 1 증가
indegree[b] += 1
# 위상 정렬 함수
def topology_sort():
result = [] # 알고리즘 수행 결과를 담을 리스트
q = deque() # 큐 기능을 위한 deque 라이브러리 사용
# 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입
for i in range(1, v + 1):
if indegree[i] == 0:
q.append(i)
# 큐가 빌 때까지 반복
while q:
# 큐에서 원소 꺼내기
now = q.popleft()
result.append(now)
# 해당 원소와 연결된 노드들의 진입차수에서 1 빼기
for i in graph[now]:
indegree[i] -= 1
# 새롭게 진입차수가 0이 되는 노드를 큐에 삽입
if indegree[i] == 0:
q.append(i)
# 위상 정렬을 수행한 결과 출력
for i in result:
print(i, end=' ')
topology_sort()
Reference
この問題について([コンセプト]10.グラフィック理論), 我々は、より多くの情報をここで見つけました https://velog.io/@dmsql698/이것이-코딩-테스트다-10.-그래프-이론テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol