python commonly used algorithm (6) - greedy algorithm, the Euclidean algorithm

1, greedy algorithm

  Greedy algorithm (also known as the greedy algorithm) means that, when the problem solving, always made in the current appears to be the best choice. In other words, not be considered as a whole the best, when he made the optimal solution in the sense of the local.

  Greedy algorithm does not guarantee the optimal solution, but the solution of the greedy algorithm on some issues is the optimal solution. To a question whether the judge will use the greedy algorithm to calculate. Greedy algorithm and other algorithms are more obvious differences, dynamic programming each sub-problem solution of all the problems are integrated to get the current best solution (global optimal solution), rather than greedily choose; backtracking is to try to choose a road, if the wrong choice, then you can "go back", that is, come back to re-select another try.

1.1 give change problem

  Assuming that store owners need to give change n dollar denomination coin is 100 yuan, 50 yuan, 20 yuan, 5 yuan, 1 yuan, how to make change for the minimum required number of coins? (Note: There is no $ 10 denominations)

  What if looking for 376 yuan change it? 100 * 50 * 1 + 3 + 5 + 20 * 1 * 1 * 1 + 1 = 375

  code show as below:

# T represent any change in the denomination of the store
t = [100, 50, 20, 5, 1]

# N represents n dollars
def change(t, n):
    m = [0 for _ in range(len(t))]
    for i, money in enumerate(t):
        m [i] = n // money # division rounded down
        n = n% money # modulo division
    return m, n

print(change(t, 376)) # ([3, 1, 1, 1, 1], 0)

1.2 knapsack problem

  Common knapsack problem knapsack and some have integer knapsack problem. That description of the problem roughly like this.

  A thief in a store found there are n goods, the i-th value of the goods Vi yuan, heavy Wi kg. He wants to take away the value as high as possible, but his backpack can hold up to W kilograms stuff. He should take those goods?

  0-1 backpack : For a commodity, or a thief put away his integrity, or leave. You can not just take part, or a commodity to take multiple (commodity bullion)

  Score backpack : For a commodity, the thief can take away any part of it. (Commodity Jinsha)

For example:

  0-1 backpacks and backpacks for the score, whether greedy algorithm can get optimal solution? why?

   Obviously, the greedy algorithm for fractional knapsack sure to get the optimal solution, we calculate the value of each item per unit weight, then they will be sorted in descending order, then began to take items, just pretend to be all kind of items you can fully armored go under if not all of the equipment installed on the inside part until backpack full.

  For this issue, it is clear knapsack sure not fill. Even if by chance you can, but can not meet all the 0-1 knapsack problem. 0-1 knapsack (knapsack problem known integer) can be divided into two: one is the number of items of each type are limited (bounded). One is an infinite number of (unbounded), that is, you want to have as many, these two can not use the greedy strategy. 0-1 backpack is typical of the first integer knapsack problem.

  Score backpack code implementation:

# Tuple representation for each commodity (price, weight)
goods = [(60, 10), (100, 20), (120, 30)]
# First we need to sort the commodity, of course, this is sorted
goods.sort(key=lambda x: x[0]/x[1], reverse=True)

# W represents knapsack capacity
def fractional_backpack(goods, w):
    # M represents the number of each item away
    total_v = 0
    m = [0 for _ in range(len(goods))]
    for i, (prize, weight) in enumerate(goods):
        if w >= weight:
            m[i] = 1
            total_v += prize
            w -= weight
        # m[i] = 1 if w>= weight else weight / w
        else:
            m[i] = w / weight
            total_v += m[i]*prize
            w = 0
            break
    return m, total_v

res1, res2 = fractional_backpack(goods, 50)
print(res1, res2)  # [1, 1, 0.6666666666666666]

1.3 splicing maximum number of questions

  There are n non-negative, which is spliced ​​to a splice integer manner as strings. How to get stitching can make the greatest integer?

  For example: 32, 94, 128, 1286, 6, 71 can be spliced ​​into a maximum integer 94716321286128.

     Note 1 : Size and string comparison integer numbers compare digital sample sizes! ! ! String comparison is to first look at the size of the first, big big, but a string of long, how short a string comparison? For example, compare 128 and 1286

  Ideas are as follows:

# Simple: When comparing two digits, etc.
a = '96'
b = '97'

a + b if a > b else b + a

# When there is a range below the median compared to how greedy algorithm it?
# We transformed the idea, string concatenation, comparison

a = '128'
b = '1286'

# String concatenation
a + b = '1281286'
b + a = '1286128'

a + b if a + b > b + a else b + a

  Splicing digital code is as follows:

from functools import cmp_to_key

= [32, 94, 128, 1286, 6, 71]

def xy_cmp(x, y):
    1 represents wherein # x> y, -1,0 empathy
    if x+y < y+x:
        return 1
    elif x+y > y+x:
        return -1
    else:
        return 0

def number_join(li):
    li = Journal (map (p, Li))
    li.sort(key=cmp_to_key(xy_cmp))
    return "".join(li)

print(number_join(li)) # 94716321286128

1.4 Activity selection

  Suppose there are n activities that take up the same piece of space, and space at a time for only one active use.

  Each activity has a start time and end time Si Fi (title time as integer) represents the activity in [Si, fi) zone occupied space. (Note: The left and right opening and closing)

  Q: What activities can arrange the activities of the venue for the most number?

   Greedy conclusion: the end of the first activities must be part of the optimal solution.

  Proof: Suppose a first end of all activities in the activity, b is the optimal solution in the first end of the event.

  If a = b, the conclusions set up

  If a! = B, the constant b, the end time later than the end of a time out at this time is replaced with the optimal solution in a b, a certain time does not overlap with other activities in the optimal solution, thus replacing the solution is the optimal solution.

   code show as below:

# Tuple represents an event (start time, end time)
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11),
              (8, 12), (2, 14), (12, 16)]

# Ensure that the activities are sorted according to the end of time, we can sort yourself first
activities.sort(key=lambda x:x[1])

def activity_selection(a):
    # First, a [0] is certainly the end of the first
    nothing = [a [0]]
    for i in range(1, len(a)):
        if a [i] [0]> = res [-1] [1]: # start time of the currently active or less active end of the last time selected
            # Do not conflict
            res.append(a[i])
    return res

res = activity_selection(activities)
print(res)

1.5 Maximum subsequence and

  Seeking the maximum of the subarray and the problem is given an integer array (array element bears with a positive), the subarray continuously seeking maximum sum. The following one by one using a greedy algorithm to traverse.

 code show as below:

def maxSubarray(li):
    s_max, s_sum = 0, 0
    for i in range(len(li)):
        s_sum + = li [i]
        s_max = max(s_max, s_sum)
        if s_sum < 0:
            s_sum = 0

    return s_max

2, Euclidean algorithm - the greatest common divisor

2.1 Definition, the greatest common divisor

  Submultiple : If the integer b be divisible by integer a, then b, is called a multiple, of a divisor of b is called.

  The greatest common divisor (Greatest the Common the Divisor) : Given two integers a, b, the maximum value of all the common divisor of two numbers is the greatest common divisor of.

  For example: the greatest common divisor of 12 and 16 is 4.

2.2 Euclidean algorithm is as follows:

  Euclidean algorithm is also known Euclidean algorithm for calculating two positive integers a, b greatest common divisor.

  • E: provided two positive integers a, b, and it is known a> b
  • E1: Order r = a% b ( '%' Representative remainder)
  • E2: If r = 0 (i.e., n is divisible by m), the end of the operation, the result is the n
  • E3: otherwise letting a = b, b = r, and returns to step E1

  Using the Euclidean algorithm (or on behalf of the modular arithmetic modulo operation provided gcd (a, b) on behalf of the greatest common divisor of a and b, mod ()) so that an equivalent of the formula:

 gcd(a,  b) =  gcd(b, a mod b ) = gcd(b, a%b)

  That is m, n divided by their greatest common divisor is equal to the remainder (r) and the greatest common divisor of n.  

  For example: gcd (60, 21) = gcd (21, 18) = gcd (18, 3) = gcd (3, 0) = 3

  Modulo means 18 is 6021, 21 pairs of the same reason over 3,18 to 18 modulo 3 0, 3 greatest common divisor of two numbers.

2.3, Euclid proved that the formula

  We proved in two steps. The first step to prove that gcd (a, b) is a divisor of b, a% b is. The second step, prove that this is the greatest common divisor.

1, demonstrate gcd (a, b) is the number of b, a% b of a convention

  1, since any two positive integers have the greatest common factor, to d.

  2, the a, b are represented as a = k1 * d b = k2 * d (k1, k2 are two constants) with the greatest common divisor d

  3, let a = k * b + c (i.e. divided by a supplier b k I C), then a = k1 * d b = k2 * d two formulas a, b, substituting the equation to give:

c = a - k * b = k1 * d - k * k2 * d, then re-extracted common divisor d, to give c = (k1 - k2 * k) * d, which shows, c has a% b is d about this number, because we began to set up any two numbers have a common divisor d, so gcd (a, b) is a divisor of b, a% b is.

  4 can be obtained by c be a multiple of the greatest common divisor d, to give evidence: gcd (a, b) = gcd (b, a mod b). So it may be larger number mn replaced with a smaller number of remainder r, the dimension reduction realized, so there is step E3. 

2, prove that we seek out common divisor is the largest

  1, mathematics is a rigorous discipline, we need strict front, we know that c (a% b) = k1 * d - k * k2 * db = k2 * d, so we only need to prove k1-k * k2, k2 can be coprime.

  2, there can be used contradiction, we assume that k1 - k * k2 = q * t k2 = p * t, substituting k1 repeat this beginning of a = k1 * d, to give a = (q * t + k * k2 ) * d, reuse distributive law of multiplication obtained: a = q * t * d + k * k2 * d, which we found, k2 * d is B, substituting it, to give a = q * t * d + b * d

  3, we will k2 = p * t start substituting b = k2 * d, to give b = p * t * d, then the progeny of the formula a = q * t * d + b * d was: . a = q * t * d + p * t * d extracting a common factor: a = (q + p) * t * d

  4, and then b = p * t * d compared to found their greatest common factor becomes t * d and start contradiction, so the assumption is not evidence to the contrary success!

2.4, how to calculate the greatest common divisor?

  1, Euclid: Euclidean algorithm (Euclidean algorithm)

  2. "Nine Chapter Arithmetic": Decreases Technique

   code show as below:

# Recursion: to ensure that a> b
def gcd(a, b):
    if b == 0:
        return a
    else:
        return gcd(b, a % b)

# Recursive method
def gcd1(a, b):
    if a < b:
        a, b = b, a
    while b > 0:
        r = a % b
        a = b
        b = r
    return a

  Because this is a pseudo-recursive, so the time complexity is not high.

2.5 Application: Calculation of fractional

   A score using the Euclidean algorithm class, support scores of the four operations.

   code show as below:

# _*_coding:utf-8_*_

class Fraction:
    def __init__(self, a, b):
        self.a = a
        self.b = b
        x = self.gcd(a, b)
        self.a /= x
        self.b /= x

    # Greatest common divisor
    def gcd(self, a, b):
        while b > 0:
            r = a % b
            a = b
            b = r
        return a

    # Least common multiple
    def zgs(self, a, b):
        # 12 16 -> 4
        # 3 * 4 * 4=48
        x = self.gcd(a, b)
        return (a * b / x)

    Adding built-in method #
    def __add__(self, other):
        # 1/12 + 1/20
        a = self.a
        b = self.b
        c = other.a
        d = other.b
        fenmu = self.zgs(b, d)
        femzi = a * (fenmu / b) + c * (fenmu / d)
        return Fraction(femzi, fenmu)

    def __str__(self):
        return "%d/%d" % (self.a, self.b)


f = Fraction(30, 16)
print(f)

 2.7 Euclidean algorithm shortcomings

   Euclidean algorithm is to calculate the number of the greatest common divisor of two traditional methods, are very well in terms of theory and practical efficiency. But there is a fatal flaw, this defect is relatively small in prime time is usually feel only when a large prime number will be revealed.

  Usually an integer of practical applications rarely exceed 64 bits (of course now allowed 128), for such integer, the number of mold between two very simple calculation. For 32-bit word length for the platform, no more than 32 calculates two integers modulo, only one instruction cycle, and calculates the integer below the mold 64, but also only a few cycles. But for larger primes, this calculation has to be designed by the user, in order to calculate the two modes over 64 integer, the user may have to employ multi-bit division is similar to the process of manual test commercial operator, this process is not only complicated, but also consume a lot of CPU time. For the case of modern cryptographic algorithms required to calculate the number of 128-bit prime above abound, such a program design eager to abandon the division and modulus.

  Stein algorithm proposed by J. Stein 1961 Nian a good solution to this defect Euclidean algorithm, Stein only integer arithmetic shifts and subtraction, in order to demonstrate the validity Stein algorithm must first be noted that the following in conclusion:

  gcd (a, a) = a, that is, a number of its own and is still common divisor of its own.
  gcd (ka, kb) = k gcd (a, b), which is the greatest common divisor calculation and multiplication operations can be exchanged. Particularly, when k = 2, described two even necessarily the greatest common divisor divisible by 2.
  When k and b are relatively prime, gcd (ka, b) = gcd (a, b), i.e. the number of only about two out of one containing factor does not affect the common denominator. Particularly, when k = 2, a description calculating a greatest common divisor of even and odd, an even number may be first divided by two.

   code show as below:

def gcd_Stein(a, b):  
    if a < b:
        a, b = b, a
    if (0 == b):
        return a
    if a % 2 == 0 and b % 2 == 0:
        return 2 * gcd_Stein(a/2, b/2)
    if a % 2 == 0:
        return gcd_Stein(a / 2, b)
    if b % 2 == 0:
        return gcd_Stein(a, b / 2)
    
    return gcd_Stein((a + b) / 2, (a - b) / 2)

References: https: //www.cnblogs.com/jason2003/p/9797750.html

https://www.cnblogs.com/Dragon5/p/6401596.html

Guess you like

Origin www.cnblogs.com/qq575654643/p/11753388.html