汪德贵
《九章算术》是中国古代数学名著,是张苍和耿寿昌所著的数学专著。其内容非常丰富,总结了战国秦汉时期的数学成就。它是当时世界上最简洁有效的应用数学,它的出现标志着中国古代数学完整体系的形成。其中一个问题是“五院合租好”,原文如下:
总共有五口井,但缺少一口和两口,比如乙一。b不足,如C不足;c不够,比如丁一;丁五氏荒,如武夷氏荒;六笔之不足,如一笔之不足,符合一切要求。
这个问题的白话解释是:五家共用一口井,甲家两根井绳和乙家一根井绳的总长度为井深;B的三根井绳和C的一根井绳的总长度为井深;C的4根井绳和丁的1根井绳的总长度为井深;丁家5根井绳和吴家1根井绳的总长度为井深;E家的六根井绳和A家的一根井绳的总长度就是井深。问:井有多深,每口井有多少根绳子?(各家的井绳长度相等)
我们也来分析一下“五口共享井”的问题,分别用Python,Graphics,APPInventor来解决。第一,创意来源
在教学生学习Python四级课程时,可利用的练习和案例并不多。于是,在搜索案例的过程中,我看到了这个“五家同井”的问题。经过研究,我发现用Python四级知识点来解决比较合适。现在分享一下。二、设计思路这是一个不定方程问题。遇到方程的时候,最初的想法是用枚举法。在100范围内跑了一圈,没有结果。说明最小正整数解必须大于100,于是范围扩大到300,结果运行很长时间不输出结果。似乎运算时间太长,等不到程序运行出结果。于是我想到了库函数sympy,这是一个用于符号计算的Python库。我在《阿基米德牛问题解析及Python验证》一文中讲过,这里就不赘述了。
通过解方程得到关系式,进而得到最小正整数解。
在用Python求解的过程中,我想再次尝试用Scratch和APPInventor求解。通过编程和运行,三个代码对比后很有启发。下面我给大家分享一下求解过程。三。设计
(一)Python编程
1.枚举法这是最直接的思维方式。如果不知道具体结果,就用枚举法测试(图1)。根据题意,分别设绳长A、B、C、D、E,井深2a+b,五个未知数满足方程2a+b=3b+c=4c+d=5d+e=6e+a,代入1到100试算。
由于运行时间较长,运行时间会被打印出来,此时显示的运行时间为222秒,数值为1到10(图2)。
2.时间复杂度
如果取值范围在100以内,时间复杂度就是10的10次方。根据跑步时间,跑10个A的将近4分钟,然后跑100个A的大约需要40分钟(图3)。
当A的值在300以内时,运行一个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的倍数,所以可以求出最小正整数解:A: 265,B: 191,C: 148,D: 129,E:76;井深:721。
即第一口井绳长265,第二口井绳长191,第三口井绳长148,第四口井绳长129,第五口井绳长76,井深721。(2)临时编程
1.基本思想是枚举,使用条件循环。2.过程描述
需要注意的是,几个条件应该是“和”,四个条件的截图不完整。如果条件满足,比如说5秒钟(图9)。
程序是五个循环,每个循环300次。a在最外层,运行一次相当于四个循环300次,即300× 300× 300次,耗时近24小时。如果A运行300次,总持续时间大约需要300天(图10)!
3.最佳化
需要优化程序,缩小取值范围。优化原则与图5中的代码一致。最外面的循环改为最小的E,最里面的循环改为A(图11)。
运行6个E大约需要3.5小时,但E越大,单次运行时间会越短,总运行时间会大大缩短(图12)。
但毕竟时间复杂度太大,Scratch效率太低,总时长还是太长。即使优化器测试了结果,也需要两天左右的时间。(C) APPInventor程序设计
1.设计理念Python测试的时候在电脑上运行速度很快,但是在手机上运行的时候更多的是依赖手机的配置,明显感觉很慢。
所以增加了直接验证的程序代码。
2.程序设计和描述
(1)变量和初始化
变量“枚举验证”是使用枚举方法或验证数据的转换开关。
变量“分解列表”是将验证时输入的数据进行分解,放入列表中供程序调用。
初始化程序。首先,初始化程序处于枚举状态,其次,提示您选择是先使用“枚举”还是“验证”(图13)。
(2)枚举
点击“枚举”按钮,输入相关数据。因为水平布局4不需要验证,并且被程序隐藏,所以在使用“枚举”时必须显示(图14)。
(3)验证
单击“验证”以验证数据是否正确。只需要连续的数据输入来验证数据,因此水平布局4被隐藏。并使用标签1的文本作为输入提示(图15)。
(4)提交
提交时先看是验证状态还是枚举状态。然后判断输入框是否为空,如果不是,则执行程序(图16)。
身份验证状态:
首先将输入框中的数据分解成一个列表,然后判断五组数据是否满足条件(图17)。
如果是,将显示五个相应的数据,并提示:验证正确;否则,提示:验证错误(图18)。
这个跑得很快。
枚举状态:
根据提示,首先输入取值范围、初始值和结束值,然后点击提交。APP的枚举界面如图19所示。
在75 ~ 80的范围内,速度很快,但是在75 ~ 300的范围内,手机一直运行没有反馈,就像死机了一样。虽然我知道程序还在后台运行,但是这个运行时间肯定会很长,没必要坚持。确定满足条件的五个值,代码如图20所示。
程序被优化。A的值是从B的开始值到结束值,而B的值是从C到结束值,以此类推。d是从E到结束值,E是从开始值到结束值。这样运行时间会大大减少,但是由于运行速度和时间直接关系到手机的配置,所以虽然计算量大大减少了,但是还是很难等到一个结果(图21)。
如果满足条件,则显示五栋房屋的绳长和井深;否则会提示起始值到结束值范围内无解。四。测试和改进
三种方法中,经过测试Python最快,APPInventor最慢(使用优化器时仍然没有结果输出),但APPInventor更直观。有兴趣的可以自己验证一下。本文就不赘述了。这也是我自己的学习心得。如果有任何问题,请随时给我您的意见!
评论列表()