Python Development [Chapter 28]: Algorithms

Keywords: Python

Algorithm basis

1. What is an algorithm?

Algorithm s: A computational process that solves problems

 

2. Review: Recursion

Two characteristics of recursion:

  • Call itself
  • Closing condition

Comparison of two important recursive functions:

# From big to small
def func3(x):
    if x > 0 :
        print(x)
        func3(x-1)

# func3(5)
# 5 4 3 2 1

# From small to large
def func4(x):
    if x > 0 :
        func4(x-1)
        print(x)

func4(5)
# 1 2 3 4 5

  

3. Time complexity

Time complexity: One thing used to evaluate the efficiency of an algorithm:

print('Hello World')            # 0(1)

for i in range(n):                  # O(n)
    print('Hello World')

for i in range(n):                   # O(n^2)
    for j in range(n):
        print('Hello World')

for i in range(n):                   # O(n^3)
    for j in range(n):
        for k in range(n):
            print('Hello World')

The first printing time complexity is O(1); the second printing time is n, so the time complexity is O(n); and the third and fourth printing time is the third power of n_and n in turn.

So what's the time complexity in the following code?

# Not O(3) but O(1)
print('Hello World')
print('Hello Python')
print('Hello Algorithm')

# Non-O(n_+n) but O(n_)
for i in range(n):
    print('Hello World')
        for j in range(n):
            print('Hello World')

# Not O(1/2n) but O(n2)
for i in range(n):
    for j in range(i): 
        print('Hello World')

Look at the following code again:

# Time complexity O(log2n) or O(logn)
while n > 1:
    print(n)
    n = n // 2

# n=64 output:
# 64
# 32
# 16
# 8
# 4
# 2

Summary:

Time complexity is a formula (unit) used to estimate the running time of the algorithm.

Generally speaking, algorithms with low time complexity are faster than those with low complexity.

Common time complexity (sorted by time)

  • O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)

Unusual time complexity (just look at it)

  • O(n!) O(2n) O(nn) …

How to judge the time complexity at a glance?

  • Loop halving process O(logn)
  • Several cycles are the complexity of the power of n.

 

4. Spatial complexity

Spatial Complexity: A Formula for Evaluating the Memory Occupancy of Algorithms

 

List lookup

List lookup: Find the specified element from the list

  • Input: List, element to be found
  • Output: Element subscripts or elements not found

1. Sequential lookup

Starting with the first element of the list, search sequentially until it is found

def linear_search(data_set, value):  
    for i in data_set:       
        if data_set[i] == value:    
            return i  
    return

Time complexity is O(n)

 

2. Binary search

Starting with the candidate area data[0:n] of the ordered list, the candidate area can be reduced by half by comparing the value to be searched with the intermediate value of the candidate area.

# Orthodox Binary Search
data = [i for i in range(9000000)]
import time
def cal_time(func):
    def inner(*args,**kwargs):
        t1 = time.time()
        re =  func(*args,**kwargs)
        t2 = time.time()
        print('Time cost:',func.__name__,t2-t1)
        return re
    return inner

@cal_time
def bin_search(data_set,val):
    low = 0
    high = len(data_set) - 1
    while low <= high:
        mid = (low + high)//2
        if data_set[mid] == val:
            return mid
        elif data_set[mid] < val:
            low = mid +1
        else:
            high = mid -1

bin_search(data, 999)
# Time cost: bin_search 0.0005002021789550781

The time complexity is O(logn). After running, you will find that it executes very quickly. Here's a comparison of the binary lookup mentioned by Alex before.

# Alex's low version
data = [i for i in range(9000000)]
import time
def cal_time(func):
    def inner(*args,**kwargs):
        t1 = time.time()
        re =  func(*args,**kwargs)
        t2 = time.time()
        print('Time cost:',func.__name__,t2-t1)
        return re
    return inner

def _binary_search(dataset, find_num):
    if len(dataset) > 1:
        mid = int(len(dataset) / 2)
        if dataset[mid] == find_num:  # find it
            print("Find figures", dataset[mid])
        elif dataset[mid] > find_num:  # The number you're looking for is on the left of mid.
            return _binary_search(dataset[0:mid], find_num)
        else:  # The number you're looking for is on the right side of mid.
            return _binary_search(dataset[mid + 1:], find_num)

@cal_time
def binary_search(dataset, find_num):
    _binary_search(dataset, find_num)

binary_search(data, 999)
# Time cost: binary_search 0.4435563087463379

 

3. Exercise

There is an information list of trainees (arranged in order of id increments) in the format of:

[
{id:1001, name:"Zhang San", age:20},
{id:1002, name:"Li Si", age:25},
{id:1004, name:"Wang Wu", age:23},
{id:1007, name:"Zhao Liu", age:33}
]

Modify the binary search code, input the student id, output the student's subscript in the list, and output the complete student information.

import random
import time

# Generating Random Lists
def  random_list(n):
    result = []
    ids = list(range(1001,1001+n))
    n1 = ['Zhao','king','Grandchildren','plum']
    n2 = ['country','love','clear','phenanthrene','']
    n3 = ['Zhen','Xuan','rain','army']
    for i in range(n):
        age = random.randint(18,60)
        id = ids[i]
        name = random.choice(n1)+random.choice(n2)+random.choice(n3)
        dic = {'id':id,'name':name,'age':age}
        result.append(dic)
    return result

# Two points search
def cal_time(func):
    def inner(*args,**kwargs):
        t1 = time.time()
        re =  func(*args,**kwargs)
        t2 = time.time()
        print('Time cost:',func.__name__,t2-t1)
        return re
    return inner

@cal_time
def bin_search(data_set,val):
    low = 0
    high = len(data_set) - 1
    while low <= high:
        mid = (low + high)//2
        if data_set[mid]['id'] == val:
            return mid
        elif data_set[mid]['id'] < val:
            low = mid +1
        else:
            high = mid -1


student_list = random_list(100000)
bin_search(student_list, 999)
# Time cost: bin_search 0.0004999637603759766
Student id query.py

Posted by Magestic on Tue, 16 Apr 2019 18:42:32 -0700