算法是程序的支柱,继上一篇的穷举法与贪婪法之后,我们来继续来了解和学习新的算法。
分治法
在一些实际场景当中,经常会出现一些复杂算式,它是由多个简单问题合成而来的,计算机并不能直接得出确定的答案,分治法非常适合于这类问题。
举个例子,想造一辆汽车,汽车由一个个零件组成,想要造出一辆汽车必须将其组成的各个部分全部装好,然后才能造出一辆汽车。
分治法的原理就是把一个难题分解为一个个计算机可以直接解答的问题,然后把子问题的解代回原式,最后得出答案。
下面就是一个使用分治法进行运算的代码,这个代码实现的功能是将一组数字当中,选定任意数字,以其为基准,左边都是比它小的。右边都是比它大的。
代码如下:
defquick_sort(origin_items, comp=lambda x, y: x
items=origin_items[:]
_quick_sort(items, 0, len(items) - 1, comp)
returnitems
def_quick_sort(items, start, end, comp):
ifstartend:
pos = _partition(items, start, end, comp)
_quick_sort(items, start, pos - 1, comp)
_quick_sort(items, pos + 1, end, comp)
def_partition(items, start, end, comp):
pivot=items[end]
i = start - 1
forjinrange(start, end):
ifcomp(items[j], pivot):
i += 1
items[i], items[j] = items[j], items[i]
items[i + 1], items[end] = items[end], items[i + 1]
returni + 1
回溯法
回溯法的原理可以这样理解,在一些游戏关卡当中会出现选项分支,选择当中提供了两个或者多个选项,当玩家选择了其中一个选项之后,发现这个选项带来的游戏体验并不好。
于是,玩家退回了选择界面,选择其他选项。若是其他选项带来的游戏体验也不好,那么就在这些选项当中选择游戏体验相对体验较好的选项,继续进行游戏进程。
回溯法就是这样的一个操作原理,在诸多选择分支当中,选择任一选项进行运算,若是得出的答案不够好,则退回分支选项重新选择,直到得出最好的答案。
关于回溯算法,有一个非常有意思的问题:
八皇后问题。
八皇后问题,是一个著名的问题,是回溯算法的典型案例。该问题是西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的西洋象棋上摆放八个皇后,使其之间不能直接互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
这个问题就应用了回溯算法,具体实现代码如下:
defqueen(A, cur=0):
ifcur == len(A):
print(A)
return
forcolinrange(len(A)):
A[cur], flag = col, True
for row in range(cur):
ifA[row] == col or abs(col - A[row]) == cur - row:
flag=False
break
ifflag:
queen(A, cur+1)
queen([None]*8)
实际上,上面所说的两种算法都涉及到一个思想:动态规划。
动态规划的基本思想就是将待求解问题分解为若干个子问题,先将子问题的答案求出保存,然后再进行其他子问题的运算,有效的规避了重复计算的出现。
在实际的开发场景中,动态规划是解决问题的一个优良思想。如果在开发当中并未应用动态规划思想,结果可能会产生大量无用的重复运算,浪费了计算机的算能力。
在这方面可以用很简单的例子来说明,就比如上述的两个算法当中,如果代码并未采用动态规划思想,可见的代码量增加,BUG出现几率直线上升,实际上线后,程序员的工作量一半就要在找BUG,修复BUG当中度过了。
算法方面的学习就此告一段落了。
在这里还是想说一句,学习新知识,尤其像编程这种实践性非常强的知识,大量的实践是必不可少的,想要在今后的职场中获得一份不错的报酬,扎实的基本功是必不可少的。
毕竟,纸上得来终觉浅,得知此事要躬行。
如果想学习更多科技知识,可以点击关注。
如果对文章中的内容有什么困惑的地方,可以在评论区提出自己的问题,学记同大家一起交流,解决各种问题,一起进步。
青年学记 陪伴着各位青年
作者:青年学记 一名不断进步的程序猿
一起学习 一起进步
走向自立
领取专属 10元无门槛券
私享最新 技术干货