Convex hull
は、この問題を解決するために実際には必要ありません。
最も時間効率的convex hull
アルゴリズムはn
全体点の数であり、そしてh
が船体上の点の数であるO(nlogh)
、です。
上記のコメントを見て、m69
を釘付けにしました!彼が記述するアルゴリズム(上に少し余分に)は、O(n)
時間に達成することができます。 Convex Hull
アイデアをスクラップしてください!
- 与えられたすべての点を囲む最小の四角形を描きます。これは、ポイントリスト上で最大&分を使用して行われます。
- 正方形内の各コーナーについて、最も外側の点に最も近い許容対角線を描きます。これは、点をループし、ユークリッド距離の式を使用することによって行われます。これは
O(n)
- 元の正方形と対角線の交点を使用して、ポリゴンの全体の周長を計算します。
ここに私のバージョンのアルゴリズム(Pythonで書かれています)があります。彼らが望むならば、人々は自由にコメントや最適化をすることができます。解決するのは楽しい問題でした。
from math import *
N = int(raw_input())
pts = []
for i in xrange(N):
p1,p2 = map(int, raw_input().split(' '))
pts.append((p1,p2))
def isBetween(a, b, c):
ab = sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
ac = sqrt((a[0]-c[0])**2 + (a[1]-c[1])**2)
bc = sqrt((b[0]-c[0])**2 + (b[1]-c[1])**2)
return abs(ac + bc - ab) < 0.01 # epsilon precision, needs < 1 in grid case
def getPoints(c):
lines = [(-1, c[0][1]+c[0][0]),(1, c[1][1]-c[1][0]),(-1,c[2][1]+c[2][0]),(1,c[3][1]-c[3][0])]
maxes = [[0,0],[0,0],[0,0],[0,0]]
for count, line in enumerate(lines):
pdist = (abs(line[0]*CH[0][0] - CH[0][1] + line[1]))/(sqrt((line[0]*line[0]) + 1))
maxes[count][0] = pdist
maxes[count][1] = CH[0]
for elem in CH[1:]:
for count, line in enumerate(lines):
pdist = (abs(line[0]*elem[0] - elem[1] + line[1]))/(sqrt((line[0]*line[0]) + 1))
if pdist < maxes[count][0]:
maxes[count][0] = pdist
maxes[count][1] = elem
for greg in range(4):
maxes[greg][1] = list(maxes[greg][1])
maxes[0][1][0] -=1
maxes[1][1][0] +=1
maxes[2][1][0] +=1
maxes[3][1][0] -=1
gregarr = []
for i in range(4):
y = lines[i][0]*(c[i][0]-maxes[i][1][0]) + maxes[i][1][1]
cornerdist = abs(c[i][1] - y)
if i == 0:
gregarr.append((c[i][0], c[i][1]+cornerdist))
gregarr.append((c[i][0]+cornerdist, c[i][1]))
elif i == 1:
gregarr.append((c[i][0]-cornerdist, c[i][1]))
gregarr.append((c[i][0], c[i][1]+cornerdist))
elif i == 2:
gregarr.append((c[i][0], c[i][1]-cornerdist))
gregarr.append((c[i][0]-cornerdist, c[i][1]))
else:
gregarr.append((c[i][0]+cornerdist, c[i][1]))
gregarr.append((c[i][0], c[i][1]-cornerdist))
return gregarr
def distance(p0, p1):
return ((p0[0] - p1[0])*(p0[0] - p1[0]) + (p0[1] - p1[1])*(p0[1] - p1[1]))**(0.5)
def f7(seq):
seen = set()
seen_add = seen.add
return [ x for x in seq if not (x in seen or seen_add(x))]
CH = pts
H = len(CH)
if H == 0:
print('0.000')
elif H == 1:
print('5.656')
else:
per = 0
minx = min(CH, key = lambda x: x[0])[0]-1
miny = min(CH, key = lambda x: x[1])[1]-1
maxx = max(CH, key = lambda x: x[0])[0]+1
maxy = max(CH, key = lambda x: x[1])[1]+1
corners = [(minx,miny),(maxx, miny),(maxx,maxy),(minx,maxy)]
arr = getPoints(corners)
arr = f7(arr)
arr.append(arr[0])
T = len(arr)
for i in range(1,T):
per += distance(arr[i-1], arr[i])
print(per)
グラフ理論やコーディングやアルゴリズムを全く考慮せずに、ポリゴンが円の内側にうまく収まるようにジオメトリから覚えています。それであなたが探しているのは円です。しかし、再びあなたは**正多角形**ではなく多角形だけを言っていました。そして、おそらく私のサークルのアイデアはうまくいかないでしょう。しかし、+1、良い質問。そして、はい、コーディングの解決策があります。しかし、それはGreedyアルゴリズムとは対照的に動的なプログラミングである可能性があります。 –
点集合の*凸包*の内側に100,000点のうち何点がありますか? –
あなたの問題は明確に規定されていません。すべての点を含む最小のポリゴンには空の領域があるため(最短のグラフに過ぎない)与えられた点の凸包を見つけることを意味しましたか? –