Junior algorithm design and analysis note summary and knowledge points sorting
Notes summary
Chapter 1 Introduction to Algorithms
1.1 algorithm and program
Algorithm definition: the method or process of solving a problem
Properties of the algorithm:
(1) Input: there are zero or more external quantities as the input of the algorithm
(2) Output: the algorithm generates at least one quantity as output
(3) Certainty: each instruction constituting the algorithm is clear and unambiguous
(4) Finiteness: the execution times of each instruction in the algorithm are limited, and the execution time of each instruction is also limited
Sometimes commonality or feasibility is added
Definition of program: it is the specific implementation of the algorithm in a programming language.
The difference between program and algorithm: the program can not meet the fourth property of the algorithm, that is, finiteness. An operating system, for example, is a program that executes in an infinite loop.
1.2 abstract mechanism of expression algorithm
In order to separate the top-level algorithm from the bottom-level algorithm, so that they do not restrict and influence each other in design, the interface between them must be abstracted. Let the bottom layer serve the top layer only through the interface, and the top layer calls the bottom operation only through the interface. This interface is the abstract data type (ADT).
1.3 description algorithm
There are many ways, such as natural language, table, high-level program language, etc
1.4 algorithm complexity analysis
The purpose of algorithm analysis: analyze the computer resources occupied by the algorithm, compare and evaluate the algorithm, and design a better algorithm
The complexity of the algorithm is the amount of computer resources required for the operation of the algorithm. The amount of time resources is called time complexity, and the amount of space resources is called space complexity.
C=F(N,I,A). N, I and A are used to represent the scale of the problem to be solved by the algorithm, the input of the algorithm and the algorithm itself, F is the determined ternary function of N, I and A, and C is the complexity
Generally, only three cases of time complexity are considered, namely, the worst case, the best case and the average case
Practice shows that the best operability and the most practical value is the time complexity in the worst case.
Complexity progressive behavior:
EXCEL about T(N),If present~T(N),Make it right N→∞happen now and then(T(N)-~T(N))/T(N)→0,Then say~T(N)yes T(N)When N→∞Asymptotic behavior of.
If there is a positive constant C and a natural number N0 such that f(N) ≤ Cg(N) when n ≥ N0, the function f(N) is said to be bounded when n is sufficiently large, and g(N) is an upper bound, which is recorded as f(N)=O(g(N)). At this time, it is also said that the order of f(N) is not higher than that of g(N).
For symbol O, there are the following operation rules:
O(f)+O(g)=O(max(f,g))
O(f)+O(g)=O(f+g)
O(f)O(g)=O(fg)
If g(N)=O(f(N)), then O(f)+O(g)=O(f)
O(Cf(N))=O(f(N)), where C is a positive constant
f=O(f)
Chapter 2 recursion and divide and conquer strategy
2.1 concept of recursion
The algorithm that directly or indirectly calls itself is called recursive algorithm. A function defined by the function itself is called a recursive function
Two elements of recursive function: boundary condition and recursive equation
Factorial function:
C++ #include<iostream> using namespace std; int factorial(int n){ if(n==0) return 1; else{ return n*factorial(n-1); } }
Fibonacci sequence:
C++ #include<iostream> using namespace std; int fibonacci(int n){ if(n<=1) return 1; else return fibonacci(n-1)+fibonacci(n-2); }
hanoi Tower:
PYTHON def hanoi(n,a,b,c): #Move the n discs on a through c to b if(n>0): hanoi(n-1,a,c,b) move(a,b) hanoi(n-1,c,b,a)
Advantages of recursive algorithm: clear structure, strong readability, easy to prove the correctness of the algorithm by mathematical induction
The disadvantage of recursive algorithm: low efficiency, which consumes more computing time and storage space than non recursive algorithm
Methods to eliminate recursion: ① use a user-defined stack to simulate the recursive call work stack of the system, so as to change the recursive algorithm into a non recursive algorithm; ② use recursion to realize the recursive function
2.2 basic idea of divide and conquer
The basic idea of divide and conquer method: decompose a problem with scale n into k smaller subproblems, which are independent of each other and the same as the original problem. These subproblems are solved recursively, and then the solutions of each subproblem are combined to obtain the solution of the original problem.
Applicable conditions of divide and conquer method:
① The scale of the problem is reduced to a certain extent, which is easy to solve.
② The problem can be decomposed into several smaller same problems. That is, the problem has the property of optimal substructure.
③ The solutions of the subproblems decomposed by the problem can be combined into the solutions of the problem.
④ There are no common subproblems among subproblems (each subproblem is independent of each other)
Steps of divide and Conquer:
divide
solve
merge
2.3 binary search technology
PYTHON def binarySearch(a,x): #a is the array and x is the number to search a=sorted(a) #a. order is required (from small to large) n=len(a) left,right=0,n-1 while(left<=right): middle=(left+right)//2 if(x==a[middle]): return middle elif(x>a[middle]): left=middle+1 else: right=middle-1 #not found return -1
In the worst case, the time complexity is O(logn)
2.4 large integer multiplication
Let X and y be n-bit binary integers, and now calculate their product xy. If you multiply directly, you need O(n^2) step, and the divide and conquer method is: divide the n-bit binary integers x and Y into 2 segments, and the length of each segment is n/2 bits:
MATHEMATICA X=[A][B],Y=[C][D],among X,Y have n Bit; A,B,C,D All n/2 position From this, we can get: X=A*2^(n/2)+B , Y=C*2^(n/2)+D XY=(A*2^(n/2)+B)(C*2^(n/2)+D) =A*C*2^n+(A*D+C*B)*2^(n/2)+B*D =A*C*2^n+((A-B)(D-C)+A*C+B*D)*2^(n/2)+B*D
The last formula seems complicated, but it only needs to do 3 times of n/2-bit integer multiplication, 6 times of addition and subtraction and 2 times of shift
2.5 Strassen matrix multiplication
For square matrices (n*n) A,B,C, C=A*B, they are divided into four submatrixes of equal size, and each submatrix is a square matrix of (n/2)*(n/2)
2.7 merge sort
PYTHON def merge(arr,left,mid,right): #left and right are the array ranges to be merged #mid is the middle subscript. The left is smaller than the median and the right is larger than the median i=left j=mid+1 #Copy a temporary array aux=arr[:] for k in range(left,right+1): #If the left pointer exceeds mid, there is still left on the right if(i>mid): arr[k]=aux[j] j=j+1 #If the right pointer exceeds right, there is left elif(j>right): arr[k]=aux[i] i=i+1 #If the left is small, the left is merged elif(aux[i]<aux[j]): arr[k]=aux[i] i=i+1 #If the right side is small else: arr[k]=aux[j] j=j+1 def mergeSort(arr,left,right): #If it has been traversed if(left>=right): return ; #Take the median value and disassemble it into left and right sides mid=(left+right)//2 #Merge and sort the left half mergeSort(arr,left,mid) #Merge and sort the right half mergeSort(arr,mid+1,right) #Merge algorithm merge(arr,left,mid,right)
The worst-case time complexity is O(nlogn)
2.8 quick sort
Steps: decomposition, recursive solution, merging
PYTHON def quicksort(arr,low,high): if low<high : index=getindex(arr,low,high) quicksort(arr,low,index-1) quicksort(arr,index+1,high) #Core of quick sorting algorithm #Function: place the number less than the reference value on the left and the number greater than the reference value on the right def getindex(arr,low,high): #The first number is the standard value by default temp=arr[low] #When the traversal is not completed, the left and right pointers do not meet while(low<high): #If the right is greater than the standard value, the right pointer moves left while((low<high)and(arr[high]>=temp)): high=high-1 #At this time, the corresponding value of the right pointer is less than the standard value, and it is copied to the left pointer position arr[low]=arr[high] #When the left is less than the standard value, the left pointer moves to the right while((low<high)and(arr[low]<=temp)): low=low+1 #At this time, the left pointer copies the corresponding value greater than the standard value to the right pointer position arr[high]=arr[low] #Assign the standard value to the position where the left and right pointers meet arr[low]=temp #At this time, all low left sides are less than or equal to arr[low], and all low right sides are greater than or equal to arr[low] return low
The average time complexity of fast scheduling is O(nlogn), and the worst time complexity is O(n^2)
2.9 linear time selection
Find the number with the largest (smallest) X in a group
Random partition algorithm is adopted
2.10 nearest point pair problem
Time complexity analysis O(nlogn)
PYTHON """ Copyright: Copyright (c) 2019 Author: Justlovesmile Title: Nearest point pair problem """ #Points sorted by x coordinate class Point1: #x. Y is the coordinate and id is the serial number def __init__(self,xx,yy,index): self.x=xx self.y=yy self.id=index #Points sorted by y coordinate class Point2(Point1): #x. y is the coordinate, and id is the sequence number when the point is sorted by X def __init__(self,xx,yy,index): self.x=xx self.y=yy self.id=index #Represents the plane point pair of the output class Pair: #a. b is the point and dist is the distance def __init__(self, aa, bb,dd): self.a=aa self.b=bb self.dist=dd #Find the distance between any two points u and V on the plane def dist(u,v): dx=u.x-v.x dy=u.y-v.y return dx*dx+dy*dy #Merge sort def merge(S,order,left,mid,right): i=left j=mid+1 aux=S[:] #Sort by x if(order=='x'): for k in range(left,right+1): if(i>mid): S[k]=aux[j] j=j+1 elif(j>right): S[k]=aux[i] i=i+1 elif(S[i].x<aux[j].x): S[k]=aux[i] i=i+1 else: S[k]=aux[j] j=j+1 #Sort by y elif(order=='y'): for k in range(left,right+1): if(i>mid): S[k]=aux[j] j=j+1 elif(j>right): S[k]=aux[i] i=i+1 elif(S[i].y<aux[j].y): S[k]=aux[i] i=i+1 else: S[k]=aux[j] j=j+1 #Merge sort def mergeSort(S,x,left,right): if(left>=right): return ; mid=(left+right)//2 mergeSort(S,x,left,mid) mergeSort(S,x,mid+1,right) merge(S,x,left,mid,right) #Calculate the closest point pair def closePair(S,Y,Z,l,r): #Two points if(r-l==1): return Pair(S[l],S[r],dist(S[l],S[r])) #Three points if(r-l==2): d1=dist(S[l],S[l+1]) d2=dist(S[l+1],S[r]) d3=dist(S[l],S[r]) if((d1<=d2)and(d1<=d3)): return Pair(S[l],S[l+1],d1) if(d2<=d3): return Pair(S[l+1],S[r],d2) else: return Pair(S[l],S[r],d3) #More than three points m=(l+r)//2 f=l g=m+1 for i in range(l,r+1): if(Y[i].id>m): Z[g]=Y[i] g=g+1 else: Z[f]=Y[i] f=f+1 #Recursive solution best = closePair(S,Z,Y,l,m) right = closePair(S,Z,Y,m+1,r) #Select the nearest point pair if(right.dist<best.dist): best=right merge(Y,"y",l,m,r) k=l #Closest to the centerline for i in range(l,r+1): if(abs(S[m].x-Y[i].x)<best.dist): Z[k]=Y[i] k=k+1 for i in range(l,k): for j in range(i+1,k): if(Z[j].y-Z[i].y<best.dist): dp=dist(Z[i],Z[j]) if(dp<best.dist): best=Pair(S[Z[i].id],S[Z[j].id],dp) #Return nearest point pair return best #One dimensional point set def cpair1(S): #Let it be positive infinity first min_d=float("inf") S=sorted(S) for i in range(1,len(S)): dist=abs(S[i]-S[i-1]) if(dist<min_d): pair=[] min_d=dist pair.append([S[i-1],S[i]]) elif(dist==min_d): pair.append([S[i-1],S[i]]) print("Closest point:") for i in pair: print(i,end=" ") print("\nMin_dist:",min_d) #2D point set def cpair2(S): Y=[] n=len(S) if(n<2): return ; #Sort by X coordinate mergeSort(S,"x",0,n-1) #Assignment of Point2 type for i in range(n): p=Point2(S[i].x,S[i].y,i) Y.append(p) #Sort by y coordinate mergeSort(Y,"y",0,n-1) Z=Y[:] return closePair(S,Y,Z,0,n-1) def main(): #Enter a one-dimensional or two-dimensional point plane model=input("Please choose model of '1' or '2':").split()[0] S=[] #One dimensional point pair if(model == '1'): point=input("Please input a group of number in order:\n").split() #If you enter a null point pair if(len(point)==0): raise ValueError("You have entered a null point pair!") #Conversion type for i in range(len(point)): S.append(int(point[i])) #Output nearest point pair cpair1(S) #Two dimensional point pair elif(model == '2'): #Input points n=int(input("Please input how many points:\n")) if(n==0): raise ValueError("You have entered 0 points!") for i in range(n): words=f"please input the No.{i+1} point (like: x y) in x order:" point=input(words).split() p=Point1(int(point[0]),int(point[1]),i) S.append(p) #Find the nearest pair of points best=cpair2(S) print(f"The closest points are ({best.a.x},{best.a.y}) and ({best.b.x},{best.b.y}).") print(f"And the distance is {best.dist**0.5}.") else: raise ValueError("This option is not available!") if __name__ == "__main__": #exception handling try: main() except Exception as e: print("Your input is illegal! The error message is as follows:") print(e)
Chapter III dynamic programming
The dynamic programming algorithm is similar to the divide and conquer method. Its basic idea is to decompose the problem to be solved into several sub problems. First solve the sub problems, and then get the solution of the original problem from the solutions of these sub problems. However, different from the divide and conquer method, the sub problems suitable for the problems solved by the dynamic programming method are often not independent of each other.
Steps of dynamic programming algorithm:
① Find out the properties of the optimal solution and characterize its structural characteristics
② Define the optimal value recursively
③ The optimal value is calculated in a bottom-up manner
④ According to the information obtained when calculating the optimal value, the optimal solution is constructed
Two basic elements of dynamic programming algorithm: optimal substructure and overlapping subproblem
Optimal substructure properties: the optimal solution of the problem includes the optimal solution of the subproblem
Overlapping subproblems: when the recursive algorithm is used to solve the problem from top to bottom, the subproblems generated each time are not always new problems, and some subproblems are calculated repeatedly
No aftereffect: after a problem is divided into stages, the state in stage I can only be obtained from the state in I+1 through the state transition equation, which has nothing to do with other states, especially with the state that has not occurred
The dynamic programming algorithm has a deformation method memo method, which is different from the filling direction of the dynamic programming algorithm "bottom-up", but the recursive direction of "top-down". A record item (memo) is established for each solved subproblem for review when necessary, and the repeated solution of the same subproblem can also be avoided
3.1 matrix multiplication problem
m(i,j) refers to the minimum number of times from A[i] to A[j] (1 ≤ I ≤ j ≤ n)
Matrix multiplicative condition: the number of columns of A is equal to the number of rows of B if A is A p × q matrix, B is A q × r matrix, then AB needs pqr times in total.
PYTHON """ Copyright: Copyright (c) 2019 Author: Justlovesmile Title: Matrix multiplication problem """ #Calculate the optimal value def matrixChain(p,m,s): #m[i][j] represents the minimum number of times required for A[i] to A[j] #s[i][j] represents the separation position corresponding to the minimum multiplication required by A[i] to A[j] n=len(p)-1 for r in range(2,n+1): for i in range(1,n-r+2): #Advance in the direction of the slash j=r+i-1 m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j] s[i][j]=i k=i+1 #Find the optimal separation k between i and j while(k<j): t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j] if(t<m[i][j]): m[i][j]=t s[i][j]=k k=k+1 #Recursive output according to S def traceback(s,i,j): if(i==j): print(f"A[{i}]",end="") return ; print("(",end="") traceback(s,i,s[i][j]) traceback(s,s[i][j]+1,j) print(")",end="") def main(): p=[] y=0 #Number of input matrices n=input("Please iuput the number of matrix:").split() #exception handling if(len(n)==0): raise ValueError("You have entered an empty matrix!") n=int(n[0]) #Enter information for each matrix for i in range(n): s=input(f"Input No.{i+1} Matrix size,eg:5 5\n").split() #Determine whether it can be multiplied by the previous item if(len(p)>=1): if(y!=int(s[0])): raise ValueError("The matrix you entered cannot be multiplied!") x,y=int(s[0]),int(s[1]) p.append(x) p.append(y) m=[] s=[] for i in range(n+1): m.append([0]*(n+1)) s.append([0]*(n+1)) matrixChain(p,m,s) traceback(s,1,n) print("\nCount times:",m[1][n]) if __name__ =="__main__": #exception handling try: main() except Exception as e: print("Your input is illegal! The error message is as follows:") print(e)
3.3 longest common subsequence
Establish recursive relationship:
PYTHON """ Copyright: Copyright (c) 2019 Author: Justlovesmile Title: Longest common subsequence problem """ def IcsLength(x,y,b): m=len(x) n=len(y) #initialization c=[] for j in range(m+1): c.append([0]*(n+1)) #Compare one by one for i in range(1,m+1): for j in range(1,n+1): #If equal, the longest common length at this time is the longest common length + 1 after removing the position if(x[i-1]==y[j-1]): c[i][j]=c[i-1][j-1]+1 #The value of record c[i][j] is obtained from the solution of the first kind of subproblem b[i][j]=1 #If the corresponding positions are not equal, compare the longest subsequence of which side of the two sequences will be longer after removing the inequality elif(c[i-1][j]>=c[i][j-1]): c[i][j]=c[i-1][j] b[i][j]=2 else: c[i][j]=c[i][j-1] b[i][j]=3 return c[m][n] #Output the longest subsequence according to b[i][j] def Ics(i,j,x,b): if(i==0 or j==0): return ; #If it is the solution of the first kind of subproblem, it means that the location is a common part if(b[i][j]==1): Ics(i-1,j-1,x,b) print(x[i-1],end="") #If it is the solution of the second kind of subproblem, it means that Zk ≠ Xm at this time elif(b[i][j]==2): Ics(i-1,j,x,b) #Zk≠Yn else: Ics(i,j-1,x,b) def main(): #Input string A=input("Please input No.1 Ics:").split() B=input("Please input No.2 Ics:").split() b=[] for i in range(len(A)+1): b.append([0]*(len(B)+1)) print("The longest length:",IcsLength(A,B,b)) Ics(len(A),len(B),A,b) if __name__=="__main__": #exception handling try: main() except Exception as e: print("Your input will not be legal! The error message is as follows:") print(e)
3.4 optimal triangulation of convex polygon
Similar to matrix multiplication
PYTHON """ Copyright: Copyright (c) 2019 Author: Justlovesmile Title: Optimal triangulation of convex polygon """ from isConvex import isConvex #Calculate the optimal value def minWeightTriangulation(n,t,s,v): #t[i][j] is a convex sub polygon vi-1, VI, The value of weight function corresponding to the optimal triangulation of VJ for r in range(2,n+1): for i in range(1,n-r+2): j=r+i-1 t[i][j]=t[i+1][j]+weight(i-1,i,j,v) s[i][j]=i k=i+1 #Traverse all edges from i to j while(k<j): u=t[i][k]+t[k+1][j]+weight(i-1,k,j,v) if(u<t[i][j]): t[i][j]=u s[i][j]=k k=k+1 #Divide the results according to s output def traceback(s,i,j): if(i==j): print(f"B[{i}]",end="") return ; print("(",end="") traceback(s,i,s[i][j]) traceback(s,s[i][j]+1,j) print(")",end="") #Calculate weights based on distance def weight(i,j,k,v): return dist(i,j,v)+dist(i,k,v)+dist(k,j,v) #Calculate distance def dist(i,j,v): return (v[i][0]-v[j][0])**2+(v[i][1]-v[j][1])**2 def main(): v=[] #You can choose to enter manually and use default values ans=input("Do you want to use default v[]:(y / n )") if(ans=="y" or ans=="Y"): v=[[6,1],[13,1],[16,4],[13,7],[6,7],[3,4]] graph="""-----@######@-------\n----#--------#------\n---#----------#-----\n--@------------@----\n---#----------#-----\n----#--------#------\n-----@######@-------\n""" print(graph) for i in v: print(f"({i[0]},{i[1]})",end=" ") elif(ans=="n" or ans=="N"): n=int(input("Please input the number of points:\n")) if(n==0): raise ValueError("You entered 0!") for i in range(n): a=input(f"Input X and Y of No.{i+1} point:(eg:X Y)\n").split() v.append([int(a[0]),int(a[1])]) else: raise ValueError("Sorry, this option is not available!") #Determine whether it is a graph polygon if(not isConvex(v)): raise ValueError("The polygon you entered is not convex! Please confirm whether to input in order!") t=[] s=[] n=len(v) #initialization for i in range(n): t.append([0]*(n)) s.append([0]*(n)) minWeightTriangulation(n-1,t,s,v) traceback(s,0,n-1) if __name__=="__main__": #exception handling try: main() except Exception as e: print("Your input is illegal! The error message is as follows:") print(e)
Determine whether it is a convex polygon
PYTHON #Determine whether it is a convex polygon ''' Calculate line expression param vertex1: Previous vertex param vertex2: Last vertex return (type, param): Returns the category of the line and its description parameters ''' def kb(vertex1, vertex2): x1 = vertex1[0] y1 = vertex1[1] x2 = vertex2[0] y2 = vertex2[1] if x1==x2: return (0, x1) # 0-vertical line if y1==y2: return (1, y1) # 1 - horizontal straight line else: k = (y1-y2)/(x1-x2) b = y1 - k*x1 return (2, k, b) # 2-inclined straight line ''' Determine whether it is a convex polygon param vertexes: A list of all vertex coordinates that make up the polygon, such as[[0,0], [50, 0], [0, 50]] return convex: Boolean type, is True Indicates that the polygon is convex, otherwise it is concave ''' def isConvex(vertexes): # The default is convex polygon convex = True # The polygon contains at least three vertices l = len(vertexes) if l<3: raise ValueError("Polygon contains at least three vertices!") # Judge the straight line composed of every two points for i in range(l): pre = i nex = (i+1)%l # Get a straight line line = kb(vertexes[pre], vertexes[nex]) # Calculate the distance (either positive or negative) between all points and lines if line[0]==0: offset = [vertex[0]-vertexes[pre][0] for vertex in vertexes] elif line[0]==1: offset = [vertex[1]-vertexes[pre][1] for vertex in vertexes] else: k, b = line[1], line[2] offset = [k*vertex[0]+b-vertex[1] for vertex in vertexes] # Calculate the product of two distances. If there is a negative number, there are two points on both sides of the line, so it is a concave polygon for o in offset: for s in offset: if o*s<0: convex = False break if convex==False: break if convex==False: break # Print judgment results if convex==True: print("The polygon is convex!") else: print("The polygon is concave!") return convex
3.9 0-1 knapsack problem
Where m(i,j) refers to the optimal value of 0-1 knapsack problem when the knapsack capacity is j and the optional items are i, i+1, ····, n
PYTHON """ Copyright: Copyright (c) 2019 Author: Justlovesmile Title: 0-1 knapsack problem --dynamic programming """ #Jump point method def knapsack_Pro(n,v,w,C,p,x): #head points to the beginning of the set of jump points at each stage head=[0 for i in range(n+1)] p[0][0],p[0][1]=0,0 left,right,pnext,head[1]=0,0,1,1 for i in range(n): k=left for j in range(left,right+1): if(p[j][0]+w[i]>C): break y=p[j][0]+w[i] m=p[j][1]+v[i] #Jump points with weight less than this number are added directly and will not be dominated while(k<=right and p[k][0]<y): p[pnext][0]=p[k][0] p[pnext][1]=p[k][1] pnext+=1 k+=1 #Two IFS judge whether the newly generated point can be added to p if(k<=right and p[k][0]==y): if(m<p[k][1]): m=p[k][1] k+=1 if(m>p[pnext-1][1]): p[pnext][0]=y p[pnext][1]=m pnext+=1 #Take out the controllable points while(k<=right and p[k][1]<=p[pnext-1][1]): k+=1 #After break ing above while(k<=right): p[pnext][0]=p[k][0] p[pnext][1]=p[k][1] pnext+=1 k+=1 left=right+1 right=pnext-1 head[i+1]=pnext traceback_Pro(n,w,v,p,head,x) def traceback_Pro(n,w,v,p,head,x): j=p[head[n]-1][0] m=p[head[n]-1][1] print("max value:",m,"max weight:",j) for i in range(n)[::-1]: for k in range(head[i],head[i+1]-1): if(p[k][0]+w[i]==j and p[k][1]+v[i]==m): x[i]=1 j=p[k][0] m=p[k][1] break def knapsack(v,w,C,m): #m[i][j] means that the backpack capacity is j, and the optional items are I, i+1, Optimal value of 0-1 knapsack problem with n n=len(v)-1 #There is only one item left for j in range(C): m[n][j] = v[n] if j>=min(w[n]-1,C) else 0 #General situation for i in range(1,n)[::-1]: for j in range(C): m[i][j] = max(m[i+1][j],m[i+1][j-w[i]]+v[i]) if j>w[i]-1 else m[i+1][j] #First item if(n>0): m[0][C-1]=m[1][C-1] if C-1>=w[0]: m[0][C-1]=max(m[0][C-1],m[1][C-1-w[0]]+v[0]) def traceback(m,w,C,x): c=C-1 for i in range(len(w)-1): #If no item I is selected, x[i]=0 if (m[i][c]==m[i+1][c]): x[i]=0 else: x[i]=1 c -= w[i] #For the last item x[len(w)-1]=1 if m[len(w)-1][c]>0 else 0 #Output format def cout(x,v,w): total_v=0 total_w=0 print("Choose:") for i in range(len(v)): if x[i]==1: print(f"No.{i+1} item: value is {v[i]} , weight is {w[i]}") total_v +=v[i] total_w +=w[i] print(f"total value: {total_v}") print(f"total weight: {total_w}") def main(): v=[] #Value list of items w=[] #Weight list of items #Enter item quantity n=input("Please input the number of items:\n") if(n=="" or n=="0"): raise ValueError("You have entered a null value or 0!") else: n=int(n) x=[0 for i in range(n+1)] #Choose two algorithms (in the textbook) ans=input("Choose Knapsack or Knapsack_Pro?(1 or 2)\n").split()[0] if ans=='1': m=[] #m(i,j) means that the backpack capacity is j, and the optional items are i, i+1, Optimal value of 0-1 knapsack problem with n for i in range(n): item=input(f"please input No.{i+1} item's value(v) and weight(w):(eg:v w)\n").split() v.append(int(item[0])) w.append(int(item[1])) C=int(input("Please input the max weight of bag:\n")) if(C<=0): raise ValueError("Backpack capacity cannot be≤0") for i in range(n): m.append([0]*C) knapsack(v,w,C,m) traceback(m,w,C,x) cout(x,v,w) elif ans=='2': for i in range(n): item=input(f"please input No.{i+1} item's value(v) and weight(w):(eg:v w)\n").split() v.append(float(item[0])) w.append(float(item[1])) #initialization p=[[0 for i in range(2)]for j in range(n*n)] C=float(input("Please input the max weight of bag:\n")) if(C<=0): raise ValueError("Backpack capacity cannot be less than or equal to 0") if(n==1): if(w[0]<=C): x[0]=1 else: x[0]=0 else: knapsack_Pro(n,v,w,C,p,x) for i in range(n): if(x[i]==1): print("choose: value:",v[i],"weight:",w[i]) else: raise ValueError(f"You entered{ans}This option is not available!") if __name__=="__main__": #exception handling try: main() except Exception as e: print("Your input is illegal! The error message is as follows:") print(e)
3.10 optimal binary search tree
Binary search tree: the element x stored in each node is greater than the element stored in any node in its left subtree and less than the element stored in any node in its right subtree
Chapter 4 greedy algorithm
Greedy algorithm: it always makes the best choice at present, that is, the greedy algorithm does not consider the overall optimization, and its choice is only the local optimal choice in a sense.
The greedy algorithm shall meet the following requirements:
Greedy selectivity: it means that the overall optimal solution of the problem can be achieved through a series of local optimal choices, that is, greedy selection
Optimal substructure property: when the optimal solution of a problem contains the optimal solution of its subproblem, the problem is said to have the optimal substructure property
The problem for which the greedy algorithm is suitable: there are n inputs, and the solution consists of a subset of the N inputs that meet some predetermined constraints, and the subset that meets the constraints is called the feasible solution of the problem. Obviously, the feasible solution is not unique in general. Those feasible solutions that make the objective function take the extreme value become the optimal solution.
Greedy algorithm is a hierarchical processing method. It first selects a metric according to the meaning of the problem, then sorts the n inputs according to this metric, and inputs them in order. If the conditions are not met, the input will not be added to the solution.
The core problem of greedy algorithm design and solution is to select the optimal measurement standard that can produce the optimal solution of the problem.
Proof of correctness of greedy algorithm:
① It is proved that the problem solved by the algorithm has an optimal substructure
② It is proved that the problem solved by the algorithm is greedy and selective
③ The algorithm makes local optimal selection according to the greedy selectivity of ②
4.2 activity arrangement
In order to select the most compatible activities, the activity with the smallest fi is selected each time, so that more activities can be selected
Metrics: in non decreasing order of end time
If ordered, O(n), if disordered, O(nlogn)
""" Copyright: Copyright (c) 2019 Author: Justlovesmile Title: Activity arrangement """ #Activity class, each activity includes start time and end time class activity(): def __init__(self,ss,ff): self.s=ss self.f=ff def greedySelector(arr,a): n=len(arr)-1 a[0]=True j=0 count=1 #Join with start time greater than the end time of the previous activity (set to True) #O(n) for i in range(1,n+1): if(arr[i].s>=arr[j].f): a[i]=True j=i count+=1 else: a[i]=False return count def main(): activities=[] #input data n=int(input("please input the number of activities:\n")) #exception handling if(n==0): raise ValueError("You entered 0!") print("Use greedy selector , activities should be ordered by the end_time.") for i in range(n): item=input("please input the begin-time and end-time:(eg: 3 6)\n").split() if(len(item)!=2): raise ValueError("The number of data you entered is illegal!") s=activity(float(item[0]),float(item[1])) activities.append(s) #Sort by end time in non decreasing order activities=sorted(activities,key=lambda x:x.f) #Initialize selection set a a=[False for i in range(n)] count=greedySelector(activities,a) print("Maximum number of activities:",count) print("Choose:",a) if __name__ == "__main__": try: main() except Exception as e: print("Your input is illegal! The error message is as follows:") print(e)
Author: justrovesmile
Link: https://blog.justlovesmile.top/posts/16050.html
Source: justrovesmile's blog
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.