728x90
Q : 이렇게 하면 모든 점들을 연결할 수 없음
A :
죄송합니다. 제가 이전 답변에서 Graham Scan 알고리즘을 이용하여 Convex Hull을 구하고, 그 Convex Hull을 이루는 점들을 순회하여 폐곡면을 그리는 예제 코드를 제공했는데, 이 코드는 모든 점을 연결하지는 않습니다.
모든 점을 연결하고 폐곡면을 그리는 방법으로는 "Minimum Spanning Tree"를 이용하는 방법이 있습니다. 이 방법은 모든 점들을 연결하는 최소 비용의 Spanning Tree를 찾은 다음, 이 Spanning Tree를 이용하여 폐곡면을 그리는 것입니다.
파이썬에서는 Kruskal 알고리즘을 이용하여 Minimum Spanning Tree를 찾을 수 있습니다. Kruskal 알고리즘을 이용하여 모든 점들을 연결하고 폐곡면을 그리는 예제 코드는 다음과 같습니다.
import math
import matplotlib.pyplot as plt
from scipy.spatial import distance
def kruskal(points):
edges = []
for i in range(len(points)):
for j in range(i+1, len(points)):
dist = distance.euclidean(points[i], points[j])
edges.append((dist, i, j))
edges.sort()
parent = list(range(len(points)))
rank = [0]*len(points)
mst = []
for edge in edges:
if len(mst) == len(points)-1:
break
weight, u, v = edge
if find(u, parent) != find(v, parent):
mst.append(edge)
union(u, v, parent, rank)
return mst
def find(u, parent):
if u != parent[u]:
parent[u] = find(parent[u], parent)
return parent[u]
def union(u, v, parent, rank):
uroot = find(u, parent)
vroot = find(v, parent)
if rank[uroot] > rank[vroot]:
parent[vroot] = uroot
else:
parent[uroot] = vroot
if rank[uroot] == rank[vroot]:
rank[vroot] += 1
# 임의의 점들을 생성
points = [(0, 0), (1, 2), (2, 3), (3, 1), (2, 0)]
# Kruskal 알고리즘을 사용하여 Minimum Spanning Tree를 구함
mst = kruskal(points)
# Minimum Spanning Tree를 순회하면서 폐곡면을 그림
plt.plot([points[u][0], points[v][0]] for w, u, v in mst)
plt.plot([points[u][0], points[v][0]] for w, u, v in mst[::-1])
plt.show()
import matplotlib.pyplot as plt
from scipy.spatial import distance
def kruskal(points):
edges = []
for i in range(len(points)):
for j in range(i+1, len(points)):
dist = distance.euclidean(points[i], points[j])
edges.append((dist, i, j))
edges.sort()
parent = list(range(len(points)))
rank = [0]*len(points)
mst = []
for edge in edges:
if len(mst) == len(points)-1:
break
weight, u, v = edge
if find(u, parent) != find(v, parent):
mst.append(edge)
union(u, v, parent, rank)
return mst
def find(u, parent):
if u != parent[u]:
parent[u] = find(parent[u], parent)
return parent[u]
def union(u, v, parent, rank):
uroot = find(u, parent)
vroot = find(v, parent)
if rank[uroot] > rank[vroot]:
parent[vroot] = uroot
else:
parent[uroot] = vroot
if rank[uroot] == rank[vroot]:
rank[vroot] += 1
# 임의의 점들을 생성
points = [(0, 0), (1, 2), (2, 3), (3, 1), (2, 0)]
# Kruskal 알고리즘을 사용하여 Minimum Spanning Tree를 구함
mst = kruskal(points)
# Minimum Spanning Tree를 순회하면서 폐곡면을 그림
plt.plot([points[u][0], points[v][0]] for w, u, v in mst)
plt.plot([points[u][0], points[v][0]] for w, u, v in mst[::-1])
plt.show()
Q : 개방된 형태로 나옴
A : 파이썬 코드의 12번째 줄에서 break를 사용하여 for 루프를 중단시키면서 최소 신장 트리의 간선 수가 정확히 $n-1$개가 아닌 경우 폐곡면을 그리는 데 문제가 발생할 수 있습니다. 이를 해결하기 위해서는 Kruskal 알고리즘의 루프 조건을 변경하여 모든 간선을 순회하면서 최소 신장 트리를 구하고, 간선 수가 $n-1$개가 아닌 경우에는 추가 간선을 선택하는 것이 좋습니다. 이렇게 하면 모든 점들을 연결하면서 폐곡면을 그릴 수 있습니다.
아래는 수정된 코드 예시입니다.
import math
import matplotlib.pyplot as plt
from scipy.spatial import distance
def kruskal(points):
edges = []
for i in range(len(points)):
for j in range(i+1, len(points)):
dist = distance.euclidean(points[i], points[j])
edges.append((dist, i, j))
edges.sort()
parent = list(range(len(points)))
rank = [0]*len(points)
mst = []
for edge in edges:
if len(mst) == len(points)-1:
break
weight, u, v = edge
if find(u, parent) != find(v, parent):
mst.append(edge)
union(u, v, parent, rank)
# 추가 간선 선택
while len(mst) < len(points)-1:
for edge in edges:
weight, u, v = edge
if find(u, parent) != find(v, parent):
mst.append(edge)
union(u, v, parent, rank)
break
return mst
def find(u, parent):
if u != parent[u]:
parent[u] = find(parent[u], parent)
return parent[u]
def union(u, v, parent, rank):
uroot = find(u, parent)
vroot = find(v, parent)
if rank[uroot] > rank[vroot]:
parent[vroot] = uroot
else:
parent[uroot] = vroot
if rank[uroot] == rank[vroot]:
rank[vroot] += 1
# 임의의 점들을 생성
points = [(0, 0), (1, 2), (2, 3), (3, 1), (2, 0)]
# Kruskal 알고리즘을 사용하여 Minimum Spanning Tree를 구함
mst = kruskal(points)
# Minimum Spanning Tree를 순회하면서 폐곡면을 그림
plt.plot([points[u][0], points[v][0]] for w, u, v in mst)
plt.plot([points[u][0], points[v][0]] for w, u, v in mst[::-1])
plt.show()
import matplotlib.pyplot as plt
from scipy.spatial import distance
def kruskal(points):
edges = []
for i in range(len(points)):
for j in range(i+1, len(points)):
dist = distance.euclidean(points[i], points[j])
edges.append((dist, i, j))
edges.sort()
parent = list(range(len(points)))
rank = [0]*len(points)
mst = []
for edge in edges:
if len(mst) == len(points)-1:
break
weight, u, v = edge
if find(u, parent) != find(v, parent):
mst.append(edge)
union(u, v, parent, rank)
# 추가 간선 선택
while len(mst) < len(points)-1:
for edge in edges:
weight, u, v = edge
if find(u, parent) != find(v, parent):
mst.append(edge)
union(u, v, parent, rank)
break
return mst
def find(u, parent):
if u != parent[u]:
parent[u] = find(parent[u], parent)
return parent[u]
def union(u, v, parent, rank):
uroot = find(u, parent)
vroot = find(v, parent)
if rank[uroot] > rank[vroot]:
parent[vroot] = uroot
else:
parent[uroot] = vroot
if rank[uroot] == rank[vroot]:
rank[vroot] += 1
# 임의의 점들을 생성
points = [(0, 0), (1, 2), (2, 3), (3, 1), (2, 0)]
# Kruskal 알고리즘을 사용하여 Minimum Spanning Tree를 구함
mst = kruskal(points)
# Minimum Spanning Tree를 순회하면서 폐곡면을 그림
plt.plot([points[u][0], points[v][0]] for w, u, v in mst)
plt.plot([points[u][0], points[v][0]] for w, u, v in mst[::-1])
plt.show()
위 코드에서는 kruskal 함수의 루프 조건을 while len(mst) < len(points)-1:으로 변경하여 추가 간선을 선택합니다. 이를 통해 모든 점들을 연결하면서
728x90
'기타' 카테고리의 다른 글
자율주행자동차가 나오면 현재 사회는 어떻게 변화할 것인가요 ? By ChatGpt (0) | 2023.02.24 |
---|---|
제레미 리프킨의 "노동의 종말" 요약 By Chat GPT (0) | 2023.02.24 |
쳇GPT 사용기 - 2302151706 - Q&A (0) | 2023.02.15 |
부국의 시작은 엄마의 각성으로부터 (0) | 2023.02.09 |
야신, 김성근 감독 - 야구 역사의 시작 (2) | 2023.01.11 |