分治思想应用:数学归纳法、递归、归并排序、MapReduce
跟黄申老师学数学系列02(python实现)
引言:
数学归纳法(Mathematical Induction)、递归、归并排序(merge sort)、MapReduce,这些方法或技术都基于一个重要的数学思想——分而治之(Divide and Conquer),简称分治,就是将一个复杂的问题,分解成两个或多个规模相同/相似的子问题(更简单一点或更接近目标一点),然后分别对这些子问题进一步细分,直到最后子问题变得非常简单。
下面通过代码对分治思想的这些实际应用进行一一展示。
数学归纳法
定义:
- 做出合理假设
- 证明基本情况,比如n=1时,是否成立
- 假设n=k-1成立,再证明n=k也成立(k为任意大于1的整数)
特点:
- 数学归纳法,已经归纳总结出规律,只要我们能够证明其正确,就没必要再逐步进行计算,以节省时间和资源。
用程序证明数学归纳法
需求:用代码证明数学归纳法,证明第k格的麦子总数是2**k-1
# params: k:第几格,result:当前格子的数量和总数
# return: 放到第k格时,是否成立class Result:def __init__(self,wheet_num = 0,wheet_total_num = 0):self.wheet_num = wheet_numself.wheet_total_num = wheet_total_numdef __str__(self):return str(self.wheet_num)+"__"+str(self.wheet_total_num)def prove(k,result):if k == 1:
# if math.pow(2,k) - 1 == 1:if 2 ** k - 1 == 1:result.wheet_num = 1result.wheet_total_num = 1return Trueelse:return Falseelse:if_previous_true = prove(k-1,result)if if_previous_true:result.wheet_num *= 2result.wheet_total_num += result.wheet_numif result.wheet_total_num == 2 ** k - 1:print resultreturn Trueprint resultreturn Falseprint(prove(64,Result()))
复制代码
注意:如果使用math.pow(2,k),因为精度的问题,k=54以后的数字是不准的。而2**k的格式则可以。待深入研究。。。
数学归纳法和递归
如果用编程来证明数学归纳法,会发现这个过程就是递归调用。
- 数学归纳法的思路:
- 看初始状态,n=1时,是否成立
- 如果n=k-1成立,那判断n=k时是否成立
- 将数学归纳法稍作转变,就是递归的一般思路:
- 假设n=k-1时,问题已经解决(或者已经求得解),那么只要求解n=k的时候,问题如何解决(或者求解是多少)
- 初始状态(n=1时),问题如何解决(或者解是多少)
递归的特点
递归,本质是用“分而治之”的思想,将复杂的问题,每次都解决一点点,并将剩下的问题转化成更简单的问题等待下次求解,如此反复,直到初始状态。这中间每次嵌套都会让函数体生成自己的局部变量,来保存大量的中间变量,省去我们复杂的操作。总之,递归的两大优点:
- “分而治之”,本质思想和数学归纳法相似:把复杂问题化解为两部分:
- 一个简单的当前步骤:可能是一次运算,一个选择、一次操作
- 另一个更简单一点的问题:通过嵌套调用
- 计算机调用嵌套函数,会保存大量中间状态和变量值,大大简化编程操作
递归例子一:限定总和,求所有可能的加加方式
需求:假设有四种面额的钱币,1 元、2 元、5 元和 10 元,而一共给我10 元,那您可以奖赏我 1 张 10 元,或者10 张 1 元,或者 5 张 1 元外加 1 张 5 元等等,如果考虑每次奖赏的金额和先后顺序,那么最终一共有多少种不同的奖赏方式?
- 法一 :
# 限定总和,求所有可能的加加方式
# params: left_total 目前总共还剩多少,current_result 当前的结果
rewards = [1,2,5,10]
current_result = []
def find(left_total,current_result):if left_total == 0:print(current_result)returnelif left_total < 0:returnelse:for i in rewards:new_result = current_result[:]new_result.append(i) # 解决目前一点点问题find(left_total - i, new_result) # 剩下的问题,留给之后嵌套调用来解决
print(find(10,[]))
复制代码
- 法二:
# 限定总和,求所有可能的加加方式
# params: current_total 目前总数是多少,current_result 当前的结果
rewards = [1,2,5,10]
total = 10
current_result = []
def find(current_total,current_result):if current_total == total:print(current_result)returnelif current_total > total:returnelse:for reward in rewards:new_result = current_result[:]new_result.append(reward)get(current_total + reward, new_result)
print(find(0,[]))
复制代码
递归例子二:
一个整数可以被分解为多个整数的乘积,例如,6 可以分解为2x3。请使用递归编程的方法,为给定的整数 n,找到所有可能的分解(1 在解中最多只能出现 1 次)。例如,输入 8,输出是可以是 1x8, 8x1, 2x4, 4x2, 1x2x2...
n = 8
def find(current_product,current_result):if current_product == n :print(current_result)returnelif current_product > n :returnelse:for i in range(1, n+1):if i != 1 or 1 not in current_result:new_result = current_result[:]new_result.append(i)find(current_product * i,new_result)find(1,[])
复制代码
归并排序
直接上代码
需求:使用归并排序(递归调用),对数字列表进行排序。
# 归并排序
# 每一步操作:是将list分成两个子children_list,将children_list的排序交给下一步,
# 这一步专注于将返回的排好序的children_list进行合并。def merge(front_list,back_list):"""对已经排好序的两个列表,进行排序"""new_list = []if not front_list:return back_listif not back_list:return front_listwhile True:if len(front_list)==0:new_list.extend(back_list)breakif len(back_list)==0:new_list.extend(front_list)breakif front_list[0] <= back_list[0]:new_list.append(front_list.pop(0))else:new_list.append(back_list.pop(0))return new_listdef merge_sort(list):if not list or len(list)==1:return listprint(len(list))front_list = list[:len(list)/2]back_list = list[len(list)/2:]front_list = merge_sort(front_list)back_list = merge_sort(back_list)return merge(front_list,back_list)list = [1,3,0]
# list = [5,6,1,0,3,8,1,6,9,-2,7,2]
list = merge_sort(list)
print(list)复制代码
分布式系统
MapReduce的架构,就是分治思想的应用。多了一步数据发送的过程。
转载于:https://juejin.im/post/5cff3801f265da1b5f264be3
分治思想应用:数学归纳法、递归、归并排序、MapReduce相关推荐
- 第2章 递归与分治思想
第2章 递归与分治思想 文章目录 第2章 递归与分治思想 一.递归 1.1 例4 归并排序.快速排序 1.2 归并排序: 1.3 快速排序 1.4 小q的数列 1.5 树 二.分治 2.1 FBI树 ...
- 【程序员必修数学课】->基础思想篇->递归(下)->分而治之从归并排序到MapReduce
递归(下) 前言 归并排序中的分治思想 分布式系统中的分治思想 1.数据分割和映射 2.归约 3.合并 总结 前言 在上一篇中,我介绍了如何使用递归,来处理迭代法中比较复杂的数值计算.但是我们知道,有 ...
- 【算法】学习笔记(4):分治思想 归并排序
分治思想,分治策略,自古有之,与人类生活息息相关,其本质是将大问题拆解为小问题,小问题转换为已知解的问题,进而求解. 军队管理,国家分级治理-- 大规模数据排序,例如10000000000万个数,规模 ...
- 【算法】归并排序:自底向上、自顶向下(分治思想)的实现
[算法]归并排序:自底向上.自顶向下(分治思想)的实现 1 自底向上 算法 import java.util.Arrays;/*** 归并排序:自底向上*/ public class Sort {/* ...
- 006.递归和分治思想
为什么80%的码农都做不了架构师?>>> 斐波那契数列的递归实现  迭代实现  递归   1.递归 定义 迭代使用的是循环结构. 递归使用的是选择结构. 优点 使用递归 ...
- 递归和分治思想及其应用
目录 递归和分治思想 一些实例 逆序输出字符串 查找数组元祖是否存在 汉诺塔问题 八皇后问题 更多: 递归和分治思想 如果可以使用迭代,尽量别使用递归.由编译原理可以知道,每次自调用的时候,计算机都需 ...
- 算法原理:大数据处理的分治思想!
↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:周彬莲,东北石油大学,Datawhale优秀学习者 引言 MapR ...
- 算法设计与分析:分治思想 - 入门
文章目录 分治思想 判断分治的条件 分治思想在排序问题的应用 求逆序对的个数 分治总结 本文参考UCAS卜东波老师的计算机算法设计与分析课程完成 分治思想 分治思想可以归纳为两点: 将一个复杂问题化简 ...
- 常见算法思想3:递归法
递归法 在计算机编程应用中,我们常常遇到代码的递归调用,事实上,递归是一种编程技巧,它是分治思想的一种重要体现.递归算法对解决大多数问题是十分有效的,它能够使算法的描述变得简洁而且易于理解. 从直观上 ...
最新文章
- lgg6 android 9,【LGG6评测】18:9奇葩比例没采用骁龙835 LG G6解析_LG G6_手机评测-中关村在线...
- 【带你重拾Redis】Redis事务
- Python学习记录day4
- Java instanceof 关键字【复习】
- 四十四、Stata统计操作和绘图
- 深入理解Three.js(WebGL)贴图(纹理映射)和UV映射
- (转)ASP.NET Core 企业开发架构概述
- POJ 2195 Going Home(最小费用最大流)题解
- 20171001~08总结
- 英文论文要怎么查重?
- 自学计算机基础知识需要什么书,学习计算机基础知识,我强烈推荐这三本书!...
- (附源码)ssm市级疫情防控管理 毕业设计 030957
- UE4 VR项目设置总结
- QT for Android串口开发
- Excel 根据序号分组
- js【详解】arr.sort()数组排序(内含十大经典排序算法的js实现)
- Android移动开发——全方面分析 Hilt 和 Koin 性能
- 基于32位版CentOS6配置符合HA模式的CDH5.7.0的Hadoop+Yarn+HBase集群
- linux raid5模拟数据丢失,Linux服务器右异步RAID-5数据恢复实例分析
- java整人_整人“病毒”代码(一)
热门文章
- 多张图片拼接到一张图
- 网管IT服务管理五个心得 (zt)
- Compile failed; see the compiler error output for details. 解决
- 函数解析|memset()函数的原理
- 腾讯微博qq说说备份导出工具_QQ空间导出助手 – 日志、相册、视频、留言板、QQ 好友列表等...
- js实现图片拖拽效果
- 电脑莫名奇妙上不去网怎么办,简单2行指令全解决ipconfig/release和ipconfig/renew
- GPS接收机学习小记(二)
- 仿屏保纯as随机飘动气泡
- 安卓11客制需求:第三方应用aida64检测蓝牙版本修改为5.0