๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ปAlgorithm/์ด๋ก 

๋ถ„ํ• ์ •๋ณต(Divide and Conquer) - ์ตœ๊ทผ์ ‘ ์ ์˜ ์Œ ์ฐพ๊ธฐ

์ตœ๊ทผ์ ‘ ์ ์˜ ์Œ(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))