王德贵
中国古代数学巨著《九章算术》是张苍、耿寿昌所撰写的一部数学专著。其内容十分丰富,总结了战国、秦、汉时期的数学成就。是当时世界上最简练有效的应用数学,它的出现标志着中国古代数学形成了完整的体系。其中有一道题是“五家共井”问题,原文如下:
五家共井,甲二绠不足,如乙一绠;乙三绠不足,如丙一绠;丙四绠不足,如丁一绠;丁五绠不足,如戊一绠;戊六绠不足,如甲一绠,皆及。
这道题的白话解释是:五家合用一口井,甲家的2根井绳和乙家1根井绳总长为井深;乙家的3根井绳和丙家的1根井绳总长为井深;丙家的4根井绳和丁家1根井绳总长为井深;丁家的5根井绳和戊家1根井绳总长为井深;戊家的6根井绳和甲家1根井绳总长为井深。问:井深、各家井绳各多少?(每家的井绳均等长)
下面我们也来分析一下“五家共井”问题,并用Python、图形化和APPInventor分别求解。
在教授学生学习Python四级课程时,合用的练习和案例并不多,于是在搜索案例过程中,看到了这个“五家共井”问题,经过研究发现比较适合用Python四级的知识点来解决,现分享出来。
这是一个不定方程问题。遇到方程最初的想法还是用枚举法,在100范围内运行后,无果。说明最小正整数解,一定比100大,于是擴大范围到300,结果运行很久也没有输出结果,看来运算时间过长了,没有能等到程序运行出结果。
于是想到库函数sympy,它是一个符号计算的Python库。我在文章《阿基米德群牛问题的分析及Python验证》里讲过,这里不再赘述。
通过解方程,得到关系式,从而求出最小正整数解。
在使用Python求解过程中,想试着再用Scratch和APPInventor求解,通过编程,运行,在对比三种代码之后很有启发,下面把求解过程分享给大家。
1.枚举法
这是一种最直接的思路,不知道具体结果,那就用枚举法测试(图1)。根据题意,设甲、乙、丙、丁、戊五根绳子分别长a、b、c、d、e,井深2a+b,5个未知数的满足方程2a+b=3b+c=4c+d=5d+e=6e+a,将1到100分别代入进行试算。
由于运行时间较长,运行时将消耗时间打印出来了,此时显示的是运行了a取值1到10的运行时间222秒(图2)。
2.时间复杂度
如果取值范围在100以内,则时间复杂度是10的10次方,按运行时间算,运行了10个a将近4分钟,那运行100个a,需要的时间就大约是40分钟(图3)。
当a的取值在300以内时,运行1个a需要的时间将近30分钟,那300个a就是近150个小时,需要6天多的时间(图4)。
这样长的运行时间程序完全无法实用,必须通过缩减无效运算来优化程序。改为将最短的绳子e作为枚举的主要参数,根据题目分析我们也能提前知道各未知数的大小关系,将d的试算起始数量从1改为从e开始,其他几个未知数以此类推。根据网络搜索答案,我已经知道e的最小正整数解小于100,b小于300。新增了变量bj=1用来判断,当获得答案后立刻跳出循环。等待一段时间能够获得答案(图5)。
运行10个e的时间将近是6分钟,随e值增大,单次运算时间还会缩短。优化后,运行时间大大缩短了,只需25分钟左右,已经获得了一组结果(图6)。
我们根据已有答案回推优化程序,最终获得了结果。但是如果我们不知道答案的范围,即使只在300范围内试算,运行也要6个小时左右。枚举法在面对这样一个不定方程的情况时,如果不知道结果的范围,那么运行时间就会非常长!必须去寻找更简捷的算法。
3.方程解法的程序设计
(1)利用sympy库函数先求出不定方程的关系式(图7)。
运行结果如图8:
因为绳长是整数,所以e一定是76的倍数,因此可以求出最小正整数解:甲:265,乙:191,丙:148,丁:129,戊:76;井深:721。
即甲家井绳长265,乙家井绳长191,丙家井绳长148,丁家井绳长129,戊家井绳长76,井深721。
1.基本思想还是枚举,利用附加条件循环。
2.程序说明
要注意的是,几个条件都应该是“与”的关系,4个条件截图不全。如果满足条件,则说5秒(图9)。
程序是5重循环,每个都是300次,a在最外层,运行了1次,就相当于运行了4重300次,就是300×300×300×300次,用了将近24小时,a要是运行300次,总时长则大约需要300天(图10)!
3.优化
必须要优化程序,缩小取值范围。优化原理和图5代码一致,最外层循环改为最小的e,最内层改为a(图11)。
运行间6个e大约3.5小时,但e越大,单次运行时间会越来越短,总运行时间大大缩短了(图12)。
但是毕竟时间复杂度太大,Scratch运行效率又太低,总时长还是太大,即使用优化程序测试结果,也需要两天左右的时间。
1.设计思路
在Python测试时,在电脑上运行速度还是很快的了,但在手机上运行,则更依赖于手机的配置,明显感觉运行得很慢很慢。
所以加上了直接验证的程序代码。
2.程序设计及说明
(1)变量和初始化
变量“枚舉验证”是使用枚举法还是验证数据的转换开关。
变量“分解列表”是在验证的时候,分解输入的数据,并放在列表中,以备程序调用。
初始化程序,一是初始化程序为枚举状态,二是提示先选择使用“枚举”还是“验证”(图13)。
(2)枚举
点击“枚举”按钮,输入相关数据。因为验证时不需要水平布局4,被程序隐藏,所以使用“枚举”时,必须让其显示出来(图14)。
(3)验证
点击“验证”即可验证数据是否正确。验证数据只需要连续输入数据,所以将水平布局4隐藏。并将标签1的文本做输入提示(图15)。
(4)提交
提交时先读取是验证状态,还是枚举状态。然后判断输入框是否为空,当不为空时,则执行程序(图16)。
验证状态:
先将输入框的数据分解成列表,再判断5组数据是否满足条件 (图17)。
如果满足,则显示五个对应的数据,并提示:验证正确,否则提示:验证错误(图18)。
这个运行速度很快。
枚举状态:
按照提示,先输入取值范围、初始值和结束值,然后点击提交即可。枚举APP界面如图19。
在75~80范围内,速度很快,但在75~300范围内,手机一直在运行过程中没有反馈,就像死机了一样,虽然我知道程序还在后台运行,但这个运行时间肯定会很久,所以就没有坚持下去的必要了。判断满足条件的5个值,代码如图20。
程序进行了优化,a的取值由b开始值到结束值,而b值由c到结束值,以此类推,d是取e到结束值,而e是从开始值到结束值。这样运行时间会减少很多,但由于运行速度和时间与手机配置直接相关,所以虽然运算量已经大大减少,还是很难去等一个结果(图21)。
如果满足条件,则显示五家的绳长和井深,否则提示在开始值到结束值范围内无解。
三种方法,经过测试,用Python运行最快,APPInventor最慢(使用优化程序仍然无结果输出),只是APPInventor更直观些。大家有兴趣,可以自行验证,本文不做赘述,这也是自己的学习心得,有不妥之处,请不吝赐教!
猜你喜欢程序设计程序优化营商环境五方面持续优化中国品牌(2021年6期)2021-08-06给Windows添加程序快速切换栏电脑爱好者(2020年6期)2020-05-26优化英语课堂教学策略的探索福建基础教育研究(2019年3期)2019-05-28简化化学平衡移动教学程序探索福建基础教育研究(2019年1期)2019-05-28促进学生认识发展 优化初中化学复习福建基础教育研究(2019年11期)2019-05-28“程序猿”的生活什么样瞭望东方周刊(2017年42期)2017-12-05英国与欧盟正式启动“离婚”程序程序环球时报(2017-03-30)2017-03-30Raptor可视化软件与程序设计计算思维的协同运用电子技术与软件工程(2017年1期)2017-03-06对分课堂在提升《C++程序设计》课程教学效果的实践与思考教育教学论坛(2017年1期)2017-02-08关于程序语言的教学改革研究电脑知识与技术(2016年19期)2016-08-18 相关热词搜索: