Definition and application example of Python rule separation and Control
This article describes the definition and application of Python division and control. We will share this with you for your reference. The details are as follows:
The problems solved by the Division and control law generally have the following characteristics:
1) The problem can be easily solved by narrowing down to a certain extent.
2) The problem can be divided into several smaller issues, that is, the problem has the optimal substructure.
3) The solutions of subproblems decomposed by this problem can be combined into the solutions of this problem;
4) Each subproblem identified by the problem is independent of each other, that is, the subproblem does not include a public subproblem.
The first feature is that most problems can be met, because the computing complexity of the problem generally increases with the increase of the problem scale;
The second feature is the premise of applying the divide and conquer method, which is also satisfied by most problems. This feature reflects the application of recursive thinking;
The third feature is the key. Whether or not the divide and conquer method can be used depends entirely on whether the question has the third feature. If the first and second features are met, you can use the greedy method or dynamic programming method.
Article 4 features involve the efficiency of the Division and control law. If the sub-problems are not independent, the division and Control Law should do a lot of unnecessary work to solve the public sub-problems repeatedly. At this time, although the Division and Control Law can be used, however, it is better to use dynamic programming.
Question 1. For a given sequence table, write a grouping Algorithm for Finding its maximum value.
# Basic subalgorithms (when the subproblem scale is less than or equal to 2) def get_max (max_list): return max (max_list) # Here it is a lazy task! # Division and Control Method version 1 def solve (init_list): n = len (init_list) if n <= 2: # if the problem scale is smaller than or equal to 2, return get_max (init_list) is finally solved) # decomposition (the subproblem scale is 2, and the last May be 1) temp_list = (init_list [I: I + 2] for I in range (0, n, 2 )) # divide and conquer, merge max_list = list (map (get_max, temp_list) # recursive (tree) solve (max_list) # divide and conquer method version 2 def solve2 (init_list ): n = len (init_list) if n <= 2: # if the problem scale is smaller than or equal to 2, return get_max (init_list) # decomposition (the subproblem scale is n/2) left_list, right_list = init_list [: n // 2], init_list [n // 2:] # recursion (tree), grouping left_max, right_max = solve2 (left_list), solve2 (right_list) # merge return get_max ([left_max, right_max]) if _ name _ = "_ main _": # Test Data test_list = [, 3, 2, 4, 45, 63, 24, 23] # calculate the maximum value print (solve (test_list) #67 print (solve2 (test_list) #67
Question 2: Give an ordered table and determine whether an element is in it.
# Subproblem algorithm (subproblem scale: 1) def is_in_list (init_list, el): return [False, true] [init_list [0] = el] # divide and conquer def solve (init_list, el): n = len (init_list) if n = 1: # If the problem scale is equal to 1, return is_in_list (init_list, el) is directly solved. # decomposition (subproblem scale: n/2) left_list, right_list = init_list [: n // 2], init_list [n // 2:] # recursion (tree), grouping, merging res = solve (left_list, el) or solve (right_list, el) return resif _ name _ = "_ main _": # Test Data test_list =, 24, 23] # search for print (solve2 (test_list, 45) # True print (solve2 (test_list, 5) # False
Question 3. Identify the k-small elements in a set of sequences, requiring Linear Time
# Division (based on Principal Component partitioning). Note: non-local division def partition (seq): pi = seq [0] # Selecting Principal Component lo = [x for x in seq [1:] if x <= pi] # all small elements hi = [x for x in seq [1:] if x> pi] # all large elements return lo, pi, hi # Find the small k element def select (seq, k): # Break down lo, pi, hi = partition (seq) m = len (lo) if m = k: return pi # solution! Elif m <k: return select (hi, k-m-1) # recursion (tree), grouping else: return select (lo, k) # recursion (tree ), if _ name _ = '_ main _': seq = [3, 4, 1, 6, 3, 7, 9, 13, 93, 0,100, 1, 2, 2, 3, 3, 2] print (select (seq, 3) #2 print (select (seq, 5) #2
Question 4. Quick sorting
# Division (based on Principal Component partitioning). Note: non-local division def partition (seq): pi = seq [0] # Selecting Principal Component lo = [x for x in seq [1:] if x <= pi] # all small elements hi = [x for x in seq [1:] if x> pi] # all large elements return lo, pi, hi # Quick sorting def quicksort (seq): # if the problem scale is smaller than or equal to 1, solve if len (seq) <= 1: return seq # Break down lo, pi, hi = partition (seq) # recursion (tree), grouping, merging return quicksort (lo) + [pi] + quicksort (hi) seq = [7, 5, 0, 6, 3, 4, 1, 9, 8, 2] print (quicksort (seq) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Question 5. Merge Sorting (Binary sorting)
# Merge sort def mergesort (seq): # split (based on the midpoint) mid = len (seq) // 2 left_seq, right_seq = seq [: mid], seq [mid:] # recursion (tree), partitioning if len (left_seq)> 1: left_seq = mergesort (left_seq) if len (right_seq)> 1: right_seq = mergesort (right_seq) # merge res = [] while left_seq and right_seq: # if both are not empty, if left_seq [-1]> = right_seq [-1]: # if the two are large at the end, the res is displayed. append (left_seq.pop () else: res. append (right_seq.pop () res. reverse () # reverse return (left_seq or right_seq) + res # Add the remaining non-empty seqseq = [7, 5, 0, 6, 3, 4, 1, 9, 8, 2] print (mergesort (seq) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Topic 6. qingta
# Tower def move (n, a, buffer, c): if n = 1: print (a, "->", c) # return else: # recursion (linear) move (n-1, a, c, buffer) move (1, a, buffer, c) # Or: print (a, "->", c) move (n-1, buffer, a, c) move (3, "a", "B", "c ")
Problem 7. climb the stairs
If you are crawling the stairs, you need n steps to reach the top. However, you can only climb one or two steps each time. How many different methods can you climb to the roof?
# Climb the stairs def climb (n = 7): if n <= 2: return n return climb (n-1) + climb (n-2) # equivalent to the Fibonacci series! Print (climb (5) #8 print (climb (7) #21
Problem 8. Given n vertices on the plane, find a pair of vertices to minimize the distance between all vertices of n points. (Recent issues)
From math import sqrt # brute force def solve (points): n = len (points) min_d = float ("inf") # minimum distance: infinity min_ps = None # closest point to for I in range (n-1): for j in range (I + 1, n ): d = sqrt (points [I] [0]-points [j] [0]) ** 2 + (points [I] [1]-points [j] [1]) ** 2) # two points away from if d <min_d: min_d = d # modify the minimum distance min_ps = [points [I], points [j] # Save the closest point to return min_ps # closest point to the nearest point (error !) Def nearest_dot (seq): # Note: seq has sorted x coordinate n = len (seq) if n <= 2: return seq # if the problem scale is equal to 2, directly solved # decomposition (subproblem scale n/2) left, right = seq [0: n/2], seq [n/2:] print (left, right) mid_x = (left [-1] [0] + right [0] [0])/2.0 # recursion, grouping lmin = (left, nearest_dot (left )) [len (left)> 2] # left-side closest point: rmin = (right, nearest_dot (right) [len (right)> 2] # closest point on the right # merge dis_l = (float ("inf"), get_distance (lmin) [len (lmin)> 1] dis_r = (float ("inf"), get_distance (rmin) [len (rmin)> 1] d = min (dis_l, dis_r) # closest point distance # processing the Strip area near the midline (approximate brute force) left = list (filter (lambda p: mid_x-p [0] <= d, left )) # right = list (filter (lambda p: p [0]-mid_x <= d, right) of the distance <= d on the left of the median )) # point mid_min = [] for p in left: for q in right: if abs (p [0]-q [0]) <= d and abs (p [1]-q [1]) <= d: # If the right part is between (d, 2d) of point p, td = get_distance (p, q) if td <= d: mid_min = [p, q] # record p, qpoint to d = td # modify the minimum distance if mid_min: return mid_min elif dis_l> dis_r: return rmin else: return lmin # Two-Point distance def get_distance (min): return sqrt (min [0] [0]-min [1] [0]) ** 2 + (min [0] [1]-min [1] [1]) ** 2) def divide_conquer (seq): seq. sort (key = lambda x: x [0]) res = nearest_dot (seq) return res # test seq = [(0, 1), (3, 2), (4, 3 ), (5, 1), (1, 2), (2, 1), (6, 2), (7, 2), (8, 3), (4, 5), (9, 0), (6, 4)] print (solve (seq) # [(6, 2), (7, 2)] # print (divide_conquer (seq) # [(6, 2), (7, 2)]
Question 9. How many possibilities are there to find the sum of values in the array seq?
'''Evaluate an algorithm: N number, where M can be used together to add a known number X. Determine the number of M. For example, seq = [1, 2, 3, 4, 5, 6, 7, 8, 9] s = 14 # And a combination of all possible numbers: 5 + 9, 6 + 81 + 4 + 9, 1 + 5 + 8, 1 + 6 + 7, 2 + 3 + 9, 2 + 4 + 8, 2 + 5 + 7, 3 + 4 + 7, 3 + 5 + 61 + 2 + 5 + 6, 1 + 3 + 4 + 6, 1 + 2 + 4 + 7, 1 + 2 + 3 + 8, 2 + 3 + 4 + 5 15 types of ''' # version 1 (pure count) def find (seq, s ): n = len (seq) if n = 1: return [0, 1] [seq [0] = s] if seq [0] = s: return 1 + find (seq [1:], s) else: return find (seq [1:], s-seq [0]) + find (seq [1:], s) # test seq = [1, 2, 3, 4, 5, 6, 7, 8, 9] s = 14 # And print (find (seq, s )) # 15seq = [11, 23, 6, 31, 8, 9, 15, 20, 24, 14] s = 40 # And print (find (seq, s) #8 # Version 2 (print) def find2 (seq, s, tmp = ''): if len (seq) = 0: # return if seq [0] = s: # Find a condition, print (tmp + str (seq [0]) # print find2 (seq [1:], s, tmp) # tail recursion --- find2 (seq [1:], s-seq [0], str (seq [0]) + '+ tmp) without seq [0) # tail recursion-Cases with seq [0] # test seq = [1, 2, 3, 4, 5, 6, 7, 8, 9] s = 14 # And find2 (seq, s) print () seq = [11, 23, 6, 31, 8, 9, 15, 20, 24, 14] s = 40 # And find2 (seq, s)