《读九章算术学Python》如何用Python编程实现均输术?附图解分析、代码实现和习题解答 - Go语言中文社区

《读九章算术学Python》如何用Python编程实现均输术?附图解分析、代码实现和习题解答


卷六 均输 以御远近劳费

主要讲述了以赋税计算为中心的比较复杂的配分比例算法,以及等差数列的问题。

第19章 均输术

Python编程要点

  • 嵌套列表的字典
  • 嵌套for循环语句
  • 字符串操作

19.1 图解九章

均,平也。输,送也。“均输术”就是按人口多少、路途远近、谷物贵贱推算赋税及徭役的方法。就算法而言,即是配分比例。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BqqhMHhD-1581040415002)(/api/storage/getbykey/original?key=1911093160e28e7a55b2)]

图19-1 问题之问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g6EGDtzz-1581040415003)(/api/storage/getbykey/original?key=19114940d1a4ef3be687)]

图19-2 问题之答

提示

图19-1和19-2所示由图解九章源码中的“图解均输术.py”自动绘制而成,我们可运行脚本文件,查看动态的绘制过程。

今有均输粟,甲县一万户,行道八日;乙县九千五百户,行道十日;丙县一万二千三百五十户,行道十三日;丁县一万二千二百户,行道二十日,各到输所(输所:收纳赋粟的场所)。凡四县赋当输二十五万斛(1斛=1石),用车一万乘。欲以道里远近、户数多少衰出之,问粟、车各几何?

答曰:甲县粟八万三千一百斛,车三千三百二十四乘。乙县粟六万三千一百七十五斛,车二千五百二十七乘。丙县粟六万三千一百七十五斛,车二千五百二十七乘。丁县粟四万五百五十斛,车一千六百二十二乘。

均输术曰:令县户数各如其本行道日数而一,以为衰。

令每县户数,各除以其各自行路天数,作为衰。即:

    甲县 10000 ÷ 8 = 1250;

    乙县 9500 ÷ 10 = 950;

    丙县 12350 ÷ 13 = 950;

    丁县 12200 ÷ 20 = 610;

甲县:乙县:丙县:丁县 = 125 :95 :95 :61

甲衰一百二十五,乙、丙衰各九十五,丁衰六十一,副并为法。以赋粟车数乘未并者,各自为实。实如法得一车。有分者,上下辈之(所求的车、牛、人数应为正整数,若得分数,可按四舍五入的法则配成整数 )。以二十五斛乘车数,即粟数。

19.2 均输术.py源码

# 导入模块                                            批注:
from common import hanzi_shu,shu_hanzi

# 获取各县户数和行道日
print("各县户数和行道日:")
xian={}                                              xian:字典,键为县名,值为各县信息的列表
hz=input().split(";")                               hz:列表,包含各县汉字字符串
for s in hz:
    for j,c in enumerate(s):
        if c == "县":
           n1=j                                      n1:“县”在字符串中的索引位置
        if c in ["户","人"]:
           n2=j                                      n2:“户”或‘人’在字符串中的索引位置
        if c == "道":
           n3=j                                      n3:“道”在字符串中的索引位置
        if c == "日":
           n4=j                                      n4:“日”在字符串中的索引位置
    xian_name=s[:n1]                                 xian_name:县名
    hu_shu=hanzi_shu(s[n1+1:n2])                     hu_shu:户数
    xing_dao_ri=hanzi_shu(s[n3+1:n4])                xing_dao_ri:行道日
    xian[xian_name]=[hu_shu,xing_dao_ri]             向xian字典中加入元素

# 获取所赋
fu={}                                                fu:字典,键为赋名,值为赋信息的列表
print("当输:")
hz=input().split(',')                               hz:列表,包含所输赋信息
for s in hz:
    fu_name=s[0]                                  fu_name:赋名 
    fu_shu=s[1:len(s)-1]                          fu_shu:赋的数量
    fu_dw=s[-1]                                   fu_dw:赋的单位,-1表示字符串最后一个元素
    fu[fu_name]=[hanzi_shu(fu_shu),fu_dw]         向fu字典中加入元素

# 列衰,副并为法
fa=0
for k in xian:                                        遍历字典xian (县)  
    # 令县户数各如其本行道日数而一,以为衰
    cui=xian[k][0]//xian[k][1]                        cui:衰
    xian[k]=cui                                       xian字典各县的值改为衰
    # 副并为法
    fa=fa+cui

for k1 in xian:                                      遍历字典xian
    cui=xian[k1]
    print(k1+"县:")
    for k2 in fu:                                    遍历字典fu
        fu_name=k2
        fu_shu=fu[k2][0]
        fu_dw=fu[k2][1]

        # 以赋粟车数乘未并者,各自为实。实如法得一。
        shi=fu_shu*cui
        zheng=int(shi/fa)
        fz=shi%fa
        fm=fa
        # 有分者,上下辈之。
        if fz*2 >fm:
            chu=zheng+1
        else:
            chu=zheng
        print(fu_name,shu_hanzi(chu)+fu_dw)

19.3 运行结果

运行脚本,解决问题,结果如图19-3所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4PjAqoy2-1581040415004)(/api/storage/getbykey/original?key=1911160a38e57d500146)]

图19-3 均输术运行结果

19.4 运行过程

上面运行过程中各字典的中间结果如下。

1.“获取各县户数和行道日

xian = {‘甲’:[10000,8],’乙’:[9500,10],’丙’:[12350,13],’丁’:[12200,20]}

2.“获取所赋

fu = {‘粟’:[250000,’斛’],’车’:[10000,’乘’]}

3.“列衰,副并为法

xian = {‘甲’:1250,’乙’:950,’丙’:950,’丁’:610}

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/epubit17/article/details/104206241
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢