python中算法定义_python算法

引言

定义:算法就是按照一定步骤解决问题的办法

属性:

正确:就是可以正确的求解问题

快速:就是时间复杂度要尽量小

有穷性:要在有限个步骤解决问题

渐进分析法为什么可以做到与算法运行硬件环境无关?

算法分析时往往假设输入规模n足够大,甚至趋近于无穷大。这样的假设,意味着我们关注的是算法运算时间的增长率,也就是,随着输入规模n的增长,T(n)的增长率。当n趋向于无穷大时,决定T(n)增长率的便是T(n)中的高次项,从而可以忽略T(n)中的低次项以及高次项前的常数项。这些低次项或者高次项前的常数项,往往是机器性能、程序设计语言的性能和编译器性能等因素产生,而这些在算法时间复杂度分析中都是需要略去的次要因素。

为什么说多项式时间复杂度的算法要优于指数时间复杂度的算法?

渐进分析与python模型

二分搜索

def binary_search(A,k):

first=0

last= len(A)-1

found=False

while first<=last and not found:

midpoint=(first+last)//2

if A[midpoint]==k:

found=True

else:

if k < A[midpoint]:

last=midpoint-1

else:

first=midpoint+1

return found

确界Θ、上界Ο、下界Ω

问题求解和代码优化

递归算法和递归函数

主分析法求时间复杂度

当f(n) < nlogba,这种情况意味着,递归树上各层结点的和从根结点开始依次递增,由于渐进表示可以去掉低次项,因此得T(n)=Θ(nlogba)。

当f(n) = nlogba,k是大于等于0的常数。这种情况意味着,递归树上各层结点的和从根结点开始并没有显著变化,因此得 T(n)=Θ( nlogba*logn)

当f(n) > nlogba,同时对于常数c<1满足af(n/b)≤cf(n)。这种情况意味着,递归树上各层结点的和从根结点开始依次递减,因此得T(n)=Θ(f(n)。

给定正整数N,计算所有长度为N但没有连续1的二分字符。比如,N=2时,输

出为[00,01,10]:当N=3时,输出为1000,001,010,100,101。

import math

N = int(input("输入N:"))

def ss(a):

a = bin(a)[2:]

j = 6

for i in a:

if j == i == '1':

return False

j = i

return True

def printN(a, N):

a = bin(i)[2:]

while len(a) < N:

a = '0' + a

print(a)

for i in range(int(math.pow(2,N))):

if ss(i):

printN(i,N)

统计逆序数问题

#_*_coding:UTF-8_*_

import random

#逆序计算的简单算法

def count_inversions_simple(A):

inv_count = 0

inv_list = []

for i in range(len(A)):

for j in range(i, len(A)):

if A[i] > A[j]:

inv_count += 1

inv_list.append([A[i],A[j]])

return inv_count, inv_list

#逆序计算的分治算法 边排序边找逆序数

#类似归并排序,加入了逆序数计算 T(n) = 2T(n/2) + O(n) = O(nlogn)

def count_inversions_dc(A):

if len(A) <= 1: #边界条件

return 0, A

middle = len(A) // 2

leftA = A[:middle]

rightA = A[middle:]

countLA, leftA = count_inversions_dc(leftA)

countRA, rightA = count_inversions_dc(rightA)

countLRA, mergedA = merger_and_count(leftA,rightA)

return countLA + countRA + countLRA, mergedA

#前提:输入的A,B是有序的

def merger_and_count(A,B):

i, j, inv_count = 0, 0, 0

alist = []

while i < len(A) and j < len(B):

if A[i] < B[j]:

alist.append(A[i])

i += 1

else: # A[i] > B[j] 则B[j]与A右边所有元素构成逆序

inv_count += len(A) - i

alist.append(B[j])

j += 1

while i < len(A):

alist.append(A[i])

i += 1

while j < len(B):

alist.append(B[j])

j += 1

return inv_count, alist

def main():

list = [random.randint(1,10) for x in range(10)]

sum, alist = count_inversions_dc(list)

print(str(list))

print("逆序数:"+str(sum)+",排序后: "+str(alist))

if __name__ == '__main__':

main()

第k小的数

方法一(课本):

#_*_coding:utf-8_*_

import random

def select_fct(array, k):

if len(array) <= 10:

array.sort()

return array[k]

pivot = get_pivot(array)

array_lt, array_gt, array_eq = patition_array(array, pivot)

if k < len(array_lt):

return select_fct(array_lt, k)

elif k < len(array_lt) + len(array_eq):

return array_eq[0]

else:

normalized_k = k - (len(array_lt) + len(array_eq))

return select_fct(array_gt, normalized_k)

def get_pivot(array):

subset_size = 5

subsets = []

num_medians = len(array) // subset_size

if (len(array) % subset_size) > 0:

num_medians += 1

for i in range(num_medians):

beg = i * subset_size

end = min(len(array), beg+subset_size)

subset = array[beg:end]

subsets.append(subset)

medians = []

for subset in subsets:

median = select_fct(subset, len(subset)//2)

medians.append(median)

pivot = select_fct(medians, len(subset)//2)

return pivot

def patition_array(array, pivot):

array_lt = []

array_gt = []

array_eq = []

for item in array:

if item < pivot:

array_lt.append(item)

elif item > pivot:

array_gt.append(item)

else:

array_eq.append(item)

return array_lt, array_gt, array_eq

def main():

num = 20

array = [random.randint(1,100) for x in range(num)]

random.shuffle(array) #random.shuffle(x[, random]):用于将一个列表中的元素打乱

random.shuffle(array)

k = 7

print(sorted(array))

kval = select_fct(array, k)

print("第八小:"+str(kval))

sorted_array = sorted(array)

assert sorted_array[k] == kval #python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假。

if __name__ == '__main__':

main()

方法二:

#_*_coding:utf-8_*_

#分治法解决第k小的数

import random

def partition(nums):

pi = nums[0]

low = [x for x in nums[1:] if x < pi]

high = [x for x in nums[1:] if x >= pi]

return low, pi, high

# 查找第 k 小的元素

def solve(nums, k):

low, pi,high = partition(nums) #分解

n = len(low)

if n+1 == k: #k+1表示第k小

return pi

elif n < k:

return solve(high,k-n-1) #减去小于和等于的

else:

return solve(low,k)

if __name__ == '__main__':

list = [random.randint(1,20) for x in range(20)]

print(sorted(list))

print(solve(list,3)) #第三小

print(solve(list,10)) #第十小

硬币找零,贪心算法

#零钱找零,pay是应付金额

def coin(pay):

m = [100, 25, 10, 5, 1]

list = []

sort_m = sorted(m, reverse=True)

for i in sort_m:

coin_count = int(pay/i)

list += [i,] * coin_count

pay -= coin_count*i

if pay <= 0:

break

return list

def main():

#硬币找零

pay = 263

print(coin(pay))

if __name__ == "__main__":

main()

digkstra算法求单源最短路径

#_*_coding:utf-8_*_

#单源最短路径问题

MAX_value = 999999

def dijkstra(graph, s): #s是源点,d(s) = 0

if graph is None: # 判断图是否为空,如果为空直接退出

return None

dist = [MAX_value,]*len(graph)

dist[s] = 0

S = []

Q = [i for i in range(len(graph))]

dist_init = [i for i in graph[s]]

while Q:

u_dist = min([d for v, d in enumerate(dist_init) if v in Q])

u = dist_init.index(u_dist)

S.append(u)

Q.remove(u)

for v, d in enumerate(graph[u]):

if 0 < d < MAX_value:

if dist[v] > dist[u]+d:

dist[v] = dist[u]+d

dist_init[v] = dist[v]

print(dist[v])

return dist #到每一个点的最短路径距离

if __name__ == '__main__':

graph_list = [ [0, 9, MAX_value, MAX_value, MAX_value, 14, 15, MAX_value],

[9, 0, 24, MAX_value, MAX_value, MAX_value,MAX_value,MAX_value],

[MAX_value, 24, 0, 6, 2, 18,MAX_value,19],

[MAX_value, MAX_value, 6, 0, 11,MAX_value,MAX_value, 6],

[MAX_value,MAX_value, 2, 11, 0, 30,20, 16],

[14,MAX_value,18,MAX_value,30,0,5,MAX_value],

[15,MAX_value,MAX_value,MAX_value,20,5,0,44],

[MAX_value,MAX_value,19,6,16,MAX_value,44,0]]

distance = dijkstra(graph_list, 0)

print(distance)

动态规划问题

#_*_coding:utf-8_*_

#动态规划

import numpy as np

import random

#斐波那契函数

memo = {} #字典

def fib2(n):

if n in memo:

return memo[n]

else:

if n <= 2:

f = 1

else:

f = fib2(n-1) + fib2(n-2)

memo[n] = f

return f

def fib_bottom_up(n):

fib = {} #存储结果的字典

for k in range(n+1):

if k <= 2:

f = 1

else:

f = fib[k-1] + fib[k-2] #填表

fib[k] = f

return fib[n]

#捡硬币

#自底向上实现递归策略

def bottom_up_coins(row_coins):

table = [None] * (len(row_coins) + 1) #申明表格

table[0] = 0

table[1] = row_coins[0]

for i in range(2, len(row_coins)+1):

table[i] = max(table[i-2] + row_coins[i-1], table[i-1]) #填表

return table

#回溯

def trace_back_coins(row_coins, table):

select = []

i = len(row_coins) #从最后一位索引

while i >= 1:

if table[i] > table[i-1]:

select.append(row_coins[i-1])

i -= 2

else:

i -= 1

return select

#子序列和的最大值

def num_max(alist): #自底向上递归

table = [None] * (len(alist)+1)

table[0] = 0

for i in range(1, len(alist)+1):

table[i] = max(table[i-1] + alist[i-1], alist[i-1]) #计算重新开始的优劣

return table

def tract_back_subseq(alist, table):

select = []

ind_max = np.argmax(table) #得到最大值索引

while ind_max >= 1:

if table[ind_max] == alist[ind_max-1] + table[ind_max-1]:

select.append(alist[ind_max-1])

ind_max -= 1

else:

select.append(alist[ind_max-1])

break

return select

if __name__ == "__main__":

list = [random.randint(1,20) for x in range(10)]

print(list)

print(fib2(10))

print(fib_bottom_up(10))

table = bottom_up_coins(list)

print(trace_back_coins(list, table))

table = num_max(list)

print(tract_back_subseq(list, table))

0,1 背包问题

#_*_coding:utf-8_*_

#0 1 背包问题

#分析: k(i, x) = max(k(i-1, x), k(i-1, x-s) + v) 物品i放入背包,不放入背包

def knapSack(W, wt, val, n):

#W是容量, wt是物品容量,val是价值, n是物品数量

k = [[0 for x in range(W+1)] for x in range(n+1)]

for i in range(n+1):

for w in range(W+1):

if i == 0 or w == 0: #不满足条件,物品或者容量为空

k[i][w] = 0

elif wt[i-1] <= w:

k[i][w] = max(val[i-1] + k[i-1][w-wt[i-1]], k[i-1][w])

else:

k[i][w] = k[i-1][w]

return k

if __name__ == "__main__":

k = knapSack(10, [1,2,3], [2,3,4], 3)

print(k)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UMAP(Uniform Manifold Approximation and Projection)是一种基于流形学习的降维算法,可以用于可视化高维数据,类似于 t-SNE 等算法。在 Python ,可以使用 umap-learn 包来实现 UMAP 算法的调用。下面是安装和使用 umap-learn 包的步骤: 1. 安装 umap-learn 包 可以使用 pip 命令来安装 umap-learn 包: ``` pip install umap-learn ``` 2. 导入 umap-learn 包 在 Python 代码,使用以下语句导入 umap-learn 包: ```python import umap ``` 3. 调用 UMAP 算法 使用 umap-learn 包的 UMAP 类来调用 UMAP 算法。以下是一个示例代码: ```python import numpy as np import umap # 生成随机数据 X = np.random.rand(100, 10) # 调用 UMAP 算法 umap_obj = umap.UMAP(n_neighbors=5, min_dist=0.3, metric='correlation') umap_result = umap_obj.fit_transform(X) # 输出降维后的结果 print(umap_result) ``` 在上面的示例代码,我们先生成了一个 100 行 10 列的随机数据集。然后,使用 UMAP 类来调用 UMAP 算法,并将参数 n_neighbors 设置为 5,min_dist 设置为 0.3,metric 设置为 correlation。最后,使用 fit_transform 方法将数据集 X 降维,并将结果保存在 umap_result 变量。最后,我们输出了降维后的结果。 注意,UMAP 算法适用于高维数据集,但是如果数据集的维度过高,UMAP 算法可能需要较长的计算时间。因此,在使用 UMAP 算法时,应该根据具体情况来调整参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值