์ต๊ทผ์ ์ ์ ์(closest pair) ๋ฌธ์ ๋ 2์ฐจ์ ํ๋ฉด์์ n๊ฐ์ ์ ์ด ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง ๋ ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ๊ฐ๊น์ด ํ ์์ ์ (๊ฑฐ๋ฆฌ)์ ์ฐพ๋ ๋ฌธ์ ์ด๋ค.
์ต๊ทผ์ ์ ์ ์์ ์ฐพ๋ ๋ฐฉ๋ฒ์ผ๋ก๋
- ๋ชจ๋ ์ ์ ๋ํ์ฌ ๊ฐ๊ฐ์ ๋ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ์ฌ ๊ฐ์ฅ ๊ฐ๊น์ด ์ ์ ์์ ์ฐพ๋ ๋ฐฉ๋ฒ (BruteForce) - O(n^2)
- n๊ฐ์ ์ ์ 1/2๋ก ๋ถํ ํ์ฌ ๊ฐ๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ์์ ์ต๊ทผ์ ์ ์ ์์ ์ฐพ๊ณ ๋ถ๋ถํด ์ค ์งง์ ์์ ์ฐพ๋ ๋ฐฉ๋ฒ (๋ถํ ์ ๋ณต)
์ด ์๋ค.
๋ถ๋ถํด๋ฅผ ์ทจํฉ(์ ๋ณต)ํ๋ ๊ณผ์ ์์ ์ค๊ฐ ์์ญ ์ฌ์ด์ ์ ์์ ๋ ๊ทผ์ ํ ์ ์ ์์ด ์กด์ฌํ ์ ์๋ค.
์ค๊ฐ ์์ญ์ ์ ๋ค์ [์ผ์ชฝ ๊ทธ๋ฃน์ ๊ฐ์ฅ ์ค๋ฅธ์ชฝ ์ ์ x ์ขํ์์ ๋ถ๋ถํด๋ฅผ ๋บ ๊ฐ๊ณผ ์ค๋ฅธ์ชฝ ๊ทธ๋ฃน์ ๊ฐ์ฅ ์ผ์ชฝ ์ ์ x์ขํ์์ ๋ถ๋ถํด๋ฅผ ๋ํ ๊ฐ ์ฌ์ด์ x ์ขํ ๊ฐ์ ๊ฐ์ง ์ ]์ด๋ค.
ex) ๋ถ๋ถํด ๊ฐ์ด 10์ด๊ณ ์ผ์ชฝ ๊ทธ๋ฃน์ ๊ฐ์ฅ ์ค๋ฅธ์ชฝ ์ ์ x์ขํ๊ฐ 21, ์ค๋ฅธ์ชฝ ๊ทธ๋ฃน์ ๊ฐ์ฅ ์ผ์ชฝ ์ ์ x์ขํ๊ฐ 24์ด๋ฉด,
x์ขํ ๊ฐ์ด 11๋ถํฐ 34 ์ฌ์ด์ ์์นํ ์ ๋ค์ด ์ค๊ฐ ์์ญ์ ํด๋นํ๋ ์ ๋ค์ด๋ค.
์๊ณ ๋ฆฌ์ฆ์ ๊ฐ๋จํ๊ฒ ์์ฑํด๋ณด๋ฉด,
#n์ ์ ์ ๊ฐฏ์๋ผ๊ณ ํ ๋
if(n==2):
return distance #๋ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ return
elif (n==3):
#์ ์ด a,b,c,๊ฐ ์์ผ๋ฉด
return min(distance) #์ธ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ ์ค ์ต์๊ฐ return
else:
mid=(left+right)//2
d1=CP(x<=mid)
d2=CP(x>mid) ##์์ญ ๋๊ฐ๋ก ๋๋
d=min(d1,d2) # ๋ ๋ถ๋ถํด ์ค ์ต๊ทผ์ ์ ๊ตฌํจ
d3=mid-d<x<mid+d ##์ค๊ฐ ์์ญ ์ค ์ต๊ทผ์ ์ ํ์
return min(d,d3) #์ค๊ฐ ์์ญ๊ณผ d ๊ฐ์ค ์์ ๊ฐ ๋ณํ
์๊ฐ๋ณต์ก๋
closestPair ์๊ณ ๋ฆฌ์ฆ์ ๋ถํ ๊ณผ์ ์ ํฉ๋ณ ์ ๋ ฌ๊ณผ ๋์ผํ๋ ํฉ๋ณ๊ณผ์ ์์์ ์ ๋ ฌํ๋ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ณ ๋ คํด์ผํจ.
k์ธต๊น์ง ๋ถํ ๋ ํ, ์ธต๋ณ๋ก ์ทจํฉ๋๋ ๊ณผ์
๊ฐ ์ธต์ ์ํ ์๊ฐ O(nlogn) * ์ธต ์ (logn) ๋ฅผ ๊ณฑํ ๊ฐ์ธ
์ด ๋๋ค.
์๊ณ ๋ฆฌ์ฆ ๊ตฌํ(python)
import random
import math
n=10
def dist(p1,p2):
return math.sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1]))
def DMZcheck(p,left,right,d):
p.sort(key=lambda x:x[1])
for i in range(left,right+1):
for j in range(i+1,right+1):
if p[j][1]-p[i][1]>d:
break
tmp=dist(p[i],p[j])
d=min(d,tmp)
return d
def closestPairIter(p):
dMin=10**6
for i in range(1,n-1):
for j in range(1,n-1):
d=dist(p[i],p[j])
if(d<dMin):
dMIn=d
iMin=i
jMin=j
print(p[iMin][0],p[iMin][1],p[jMin][0],p[jMin][1],dMin)
def closestPairRecur(p,left,right):
size=right-left+1 #์ ์ ๊ฐฏ์
if(size==2):
return dist(p[left],p[right]) #๋ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ return
elif(size==3):
a=dist(p[left],p[left+1])
b=dist(p[left+1],p[right])
c=dist(p[left],p[left+2])
return min(a,b,c) #์ธ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ ์ค min ๊ฐ return
##๋ถํ
else:
mid=(left+right)//2
a=closestPairRecur(p,left,mid)
b=closestPairRecur(p,mid+1,right)
return DMZcheck(p,left,right,min(a,b)) #์ค๊ฐ์์ญ
#์ค๊ฐ ์์ญ์ ์ ๋ณต ์ ๋ง์ง๋ง์ ๊ณ ๋ ค ํ์ ์ ๋ณต ์์(๊ฒฐ๊ณผ ์ทจํฉ)
p=[[0,0] for _ in range(n)]
for i in range(n):
p[i][0]=random.randint(0,100)
p[i][1]=random.randint(0,50)
p.sort() #x์ขํ ์ ๋ ฌ
print(p)
closestPairIter(p)
print("-"*10)
print(closestPairRecur(p,0,n-1))
'๐ปAlgorithm > ์ด๋ก ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๊ทธ๋ฆฌ๋(Greedy) - ์ต์์ ์ฅํธ๋ฆฌ(MST) (0) | 2022.04.18 |
---|---|
๋์ ๊ณํ ์๊ณ ๋ฆฌ์ฆ(DP/Dynamic Programming) (0) | 2022.04.18 |
๊ทธ๋ฆฌ๋(Greedy)/ํ์ ๊ธฐ๋ฒ (0) | 2022.04.15 |
๋ถํ ์ ๋ณต(Divide and Conquer) (0) | 2022.04.10 |