分治算法

分治算法

一.归并排序

from IPython.display import Image
Image(filename="./data/10_01.png",width=800,height=960)

output_2_0.png

递归法

def mergeSortRecursive(myList):
    if len(myList)<2:
        return
    
    cut=len(myList)//2
    listA=myList[:cut]
    listB=myList[cut:]
    
    mergeSortRecursive(listA)
    mergeSortRecursive(listB)
    
    pointerA=0
    pointerB=0
    
    counter=0
    
    while (pointerA<len(listA) and pointerB<len(listB)):
        if (listA[pointerA]<listB[pointerB]):
            myList[counter]=listA[pointerA]
            pointerA+=1
            
        else:
            myList[counter]=listB[pointerB]
            pointerB+=1
            
        counter+=1
        
    while pointerA<len(listA):
        myList[counter]=listA[pointerA]
        pointerA+=1
        counter+=1
        
    while pointerB<len(listB):
        myList[counter]=listB[pointerB]
        pointerB+=1
        counter+=1
listX=[6,3,-2,0,-1,5,9,7]
mergeSortRecursive(listX)
print(listX)
[-2, -1, 0, 3, 5, 6, 7, 9]

迭代法

Image(filename="./data/10_02.png",width=800,height=960)

output_7_0.png

def mergeSortIterate(myList):
    length=len(myList)
    
    n=1
    
    while n<length:
        for i in range(0,length,n*2):
            listA=myList[i:i+n]
            listB=myList[i+n:i+n*2]
            
            pointerA=0
            pointerB=0
            
            counter=i
            
            while (pointerA<len(listA) and pointerB<len(listB)):
                if (listA[pointerA]<listB[pointerB]):
                    myList[counter]=listA[pointerA]
                    pointerA+=1
                    
                else:
                    myList[counter]=listB[pointerB]
                    pointerB+=1
                counter+=1
                
                
            while pointerA<len(listA):
                myList[counter]=listA[pointerA]
                pointerA+=1
                counter+=1
                
            while pointerB<len(listB):
                myList[counter]=listB[pointerB]
                pointerB+=1
                counter+=1
                
        n=n*2
myList=[-2,9,0,8,5,-4,8]
mergeSortIterate(myList)
print(myList)
[-4, -2, 0, 5, 8, 8, 9]

二.连续子列表的最大和

Image(filename="./data/10_03.png",width=800,height=960)

output_11_0.png

Image(filename="./data/10_04.png",width=800,height=960)

output_12_0.png

def maxSubArray(nums):
    if nums==[]:
        return
    if len(nums)==1:
        return nums[0]
    
    cut=len(nums)//2
    leftSum=maxSubArray(nums[:cut])
    rightSum=maxSubArray(nums[cut:])
    
    leftMiddleSum=0
    maxL=0
    rightMiddelSum=0
    maxR=0
    
    for i in range(cut-1,-1,-1):
        leftMiddleSum+=nums[i]
        maxL=max(leftMiddleSum,maxL)
        
    for i in range(cut+1,len(nums),1):
        rightMiddelSum+=nums[i]
        maxR=max(rightMiddelSum,maxR)
        
    return (max(leftSum,maxL+nums[cut]+maxR,rightSum))
maxSum=maxSubArray([-2,1,-3,4,-1,2,1,-5,4])
print(maxSum)
6

三.凸包问题

Image(filename="./data/10_05.png",width=800,height=960)

output_16_0.png

Image(filename="./data/10_06.png",width=800,height=960)

output_17_0.png

from math import sqrt

solution=[]

def convexHull(points):
    # 少于三点
    if len(points)<=3:
        return points
    # 引用全局变量
    global solution
    
    # 按x坐标排序
    points.sort(key=lambda x:x[0])
    
    left_most=points[0]
    right_most=points[len(points)-1]
    
    solution.append(left_most)
    solution.append(right_most)
    
    # 分治:上包
    helper(points,left_most,right_most,True)
    # 分治:下包
    helper(points,left_most,right_most,False)
    return solution

# 参数为:点集合,最左点,最右点,布尔值(上包为True,下包为False)
def helper(points,left_most,right_most,upBool):
    global solution
    
    if len(points)<=1:
        return
    
    l=lineHelper(left_most,right_most)
    
    # 上包,直线之上的点集合
    if upBool:
        up=[]
        max_distance=0
        max_point=()
        
        for point in points:
            distance=0-(l[0]*point[0]+l[1]*point[1]+l[2])/sqrt(l[0]*l[0]+l[1]*l[1])
            
            if distance>0:
                up.append(point)
                
                if distance>max_distance:
                    max_distance=distance
                    max_point=point
                    
        if max_point!=():
            # 最远点加入顶点集
            solution.append(max_point)
        # 递归左上包
        helper(up,left_most,max_point,True)
        # 递归右上包
        helper(up,max_point,right_most,True)
        
    else:
        down=[]
        min_distance=0
        min_point=()
        
        for point in points:
            distance=0-(l[0]*point[0]+l[1]*point[1]+l[2])/sqrt(l[0]*l[0]+l[1]*l[1])
            
            if distance<0:
                down.append(point)
                
                if distance<min_distance:
                    min_distance=distance
                    min_point=point
                    
        if min_point!=():
            solution.append(min_point)
        
        # 递归左下包
        helper(down,left_most,min_point,False)
        # 递归右下包
        helper(down,min_point,right_most,False)
        
def lineHelper(point1,point2):
    if (point1[0]-point2[0])!=0:
        m=(point1[1]-point2[1])/(point1[0]-point2[0])
        c=point1[1]-m*point1[0]
        return [m,-1,c]
    else:
        return [1,0,point1[0]]
points=[(0,0),(0,4),(-4,0),(5,0),(0,-6),(1,0)]
convexHull(points)
[(-4, 0), (5, 0), (0, 4), (0, -6)]

四.多项式乘法

Image(filename="./data/10_07.png",width=800,height=960)

output_21_0.png

Image(filename="./data/10_08.png",width=800,height=960)

output_22_0.png

from cmath import pi
from cmath import exp
import cmath
import numpy as np

def FFT(A,w):
    length=len(A)
    
    if length==1:
        return [A[0]]
    
    else:
        A_even=[]
        A_odd=[]
        
        for i in range(0,length//2):
            A_even.append(A[2*i])
            A_odd.append(A[2*i+1])
            
        F_even=FFT(A_even,w**2)
        F_odd=FFT(A_odd,w**2)
        
        x=1
        values=[None]*length
        
        for i in range(0,length//2):
            values[i]=F_even[i]+x*F_odd[i]
            values[i+length//2]=F_even[i]-x*F_odd[i]
            x=x*w
        return values

def solver(A,B):
    length=len(A)+len(B)-1
    
    n=1
    
    while 2**n<length:
        n+=1
        
    length=2**n
    
    A.extend([0]*(length-len(A)))
    B.extend([0]*(length-len(B)))
    
    w=exp(2*pi*1j/length)
    A_values=FFT(A,w)
    B_values=FFT(B,w)
    C_values=[A_values[i]*B_values[i] for i in range(length)]
    
    result=[int((x/length).real) for x in FFT(C_values,w**(-1))]
    
    while result[-1]==0:
        del result[-1]
        
    print(result)
solver([3,2,3,4],[2,0,1])
[5, 3, 9, 10, 3, 4]
posted @ 2019-11-09 18:25  LQ6H  阅读(141)  评论(0编辑  收藏  举报