从穷举法到插板法:Python解决求和为12的正整数组合20240619

从穷举法到插板法:Python解决求和为12的正整数数学问题

在这篇博客中,我们将使用Python来解决一个有趣的小学数学问题:求出所有正整数组合,使得这些数的和为12。我们将演示如何找到这些组合,并计算每个组合的排列数,最终得到所有可能的排列组合数。

问题描述

我们的问题是找到所有满足 (a + b + c + d = 12) 的正整数组合,并计算每个组合的排列数。我们将展示完整的过程,包括如何找到所有组合,计算每个组合的排列数,并汇总最终结果。

解题思路2:插板法
把 12 看成 12 个 1,12 个 1 之间有 11 个间隔,要把 12 分成 4 个正整数的和,相当于在 11 个间隔中插入 3 个隔板,所以共有组合数 𝐶(11,3)=165。

from math import comb
n = 12
k = 4
combinations_count = comb(n - 1, k - 1)
print(f"Using the stars and bars method, the total number of unique combinations is: {combinations_count}")

结果
Using the stars and bars method, the total number of unique combinations is: 165

解题思路2:穷举法

我们将使用Python的两个步骤来解决这个问题:

  1. 找到所有满足条件的组合。
  2. 计算每个组合的排列数。

步骤1:找到所有组合

组合数的思考:考虑到每个变量至少为1,因此直接开始分配剩余的8个单位。
一个变量为8:如 (8, 0, 0, 0) => (9, 1, 1, 1)
一个变量为7:如 (7, 1, 0, 0) => (8, 2, 1, 1)
一个变量为6:如 (6, 2, 0, 0) => (7, 3, 1, 1)
依此类推直到 (2, 2, 2, 2) => (3, 3, 3, 3)
总共15种情况:通过系统的分配,可以得到15种组合

我们使用itertools库中的combinations_with_replacement函数来生成所有可能的组合。

from itertools import combinations_with_replacement

def find_solutions(n, k):
    solutions = set()
    for combo in combinations_with_replacement(range(1, n), k):
        if sum(combo) == n:
            solutions.add(tuple(sorted(combo)))
    return solutions

n = 12
k = 4
solutions = find_solutions(n, k)
solutions_list = sorted(solutions)

print(f"Total number of unique combinations: {len(solutions_list)}")
print("Combinations:")
for combination in solutions_list:
    print(combination)

运行结果:

Total number of unique combinations: 15
Combinations:
(1, 1, 1, 9)
(1, 1, 2, 8)
(1, 1, 3, 7)
(1, 1, 4, 6)
(1, 1, 5, 5)
(1, 2, 2, 7)
(1, 2, 3, 6)
(1, 2, 4, 5)
(1, 3, 3, 5)
(1, 3, 4, 4)
(2, 2, 2, 6)
(2, 2, 3, 5)
(2, 2, 4, 4)
(2, 3, 3, 4)
(3, 3, 3, 3)

步骤2:计算排列数

接下来,我们计算每个组合的排列数。我们使用math库中的factorial函数来实现这个过程。

from math import factorial
from collections import Counter

def count_permutations(combination):
    counts = Counter(combination)
    denominator = 1
    for count in counts.values():
        denominator *= factorial(count)
    return factorial(len(combination)) // denominator

# 计算每个组合的排列数
permutation_counts = [count_permutations(comb) for comb in solutions_list]

# 统计每个排列数出现的次数
counter = Counter(permutation_counts)

# 生成输出表达式
output_parts = [f"{count}x{permutation_counts.count(count)}" for count in set(permutation_counts)]

# 计算总排列数
total_permutations = sum(permutation_counts)

output_expression = " + ".join(output_parts)

print(f"\nTotal number of unique solutions: {total_permutations}")
print("Detailed calculation:")
print(output_expression)

print("\nEach combination with its permutation count:")
for combination, perm_count in zip(solutions_list, permutation_counts):
    print(f"{combination} - {perm_count} permutations")

运行结果:

Total number of unique solutions: 165
Detailed calculation:
4x2 + 12x8 + 24x2 + 6x2 + 1x1

Each combination with its permutation count:
(1, 1, 1, 9) - 4 permutations
(1, 1, 2, 8) - 12 permutations
(1, 1, 3, 7) - 12 permutations
(1, 1, 4, 6) - 12 permutations
(1, 1, 5, 5) - 6 permutations
(1, 2, 2, 7) - 12 permutations
(1, 2, 3, 6) - 24 permutations
(1, 2, 4, 5) - 24 permutations
(1, 3, 3, 5) - 12 permutations
(1, 3, 4, 4) - 12 permutations
(2, 2, 2, 6) - 4 permutations
(2, 2, 3, 5) - 12 permutations
(2, 2, 4, 4) - 6 permutations
(2, 3, 3, 4) - 12 permutations
(3, 3, 3, 3) - 1 permutation

可视化结果

为了更好地展示每个组合的排列数及其频率,我们使用matplotlib生成一个条形图。这样可以直观地看到每个组合的排列数。

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 设置字体以支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用SimHei字体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号

# 数据
labels = [str(combination) for combination in solutions_list]
counts = permutation_counts

# 创建条形图
plt.figure(figsize=(15, 8))
plt.barh(labels, counts, color='skyblue')
plt.xlabel('排列数')
plt.ylabel('组合')
plt.title('每个组合的排列数')
plt.grid(axis='x', linestyle='--', alpha=0.7)
for index, value in enumerate(counts):
    plt.text(value, index, str(value))
plt.tight_layout()

# 保存为图片
plt.savefig('permutation_counts.png', dpi=300, bbox_inches='tight')
plt.show()

通过生成的条形图,可以直观地看到每个组合的排列数,并理解每个组合在总排列数中的贡献。

总结

穷举法在解决复杂问题时非常有用,特别是在没有明确数学模型的情况下。其关键在于有一个清晰的规划和分类思路,确保所有可能性都被考虑到且不重复、不遗漏。在这篇博客中,我们展示了如何使用Python解决一个小学数学问题,并通过组合和排列的方法找出所有满足条件的组合及其排列数。这不仅帮助孩子们更好地理解数学问题,还展示了计算机编程在解决实际问题中的强大能力。

通过这篇博客,我们探索了两种不同的解题思路:穷举法和插板法。穷举法通过系统地枚举所有可能的组合来找到答案,而插板法则通过巧妙的数学转化快速解决问题。这两种方法展示了数学问题的多样性和灵活性,帮助孩子们学到多种解题技巧,培养他们的创造力和思考能力。

无论是直接的穷举法,还是巧妙的插板法,每种方法都有其独特的价值和应用场景,鼓励孩子们在解决问题的过程中不断创新和思考。

希望这篇博客对您有所帮助。如果有任何问题或建议,欢迎留言讨论。

完整代码

以下是完整的Python代码,包含了所有步骤和可视化部分:

from itertools import combinations_with_replacement
from math import factorial
from collections import Counter
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

def find_solutions(n, k):
    solutions = set()
    for combo in combinations_with_replacement(range(1, n), k):
        if sum(combo) == n:
            solutions.add(tuple(sorted(combo)))
    return solutions

def count_permutations(combination):
    counts = Counter(combination)
    denominator = 1
    for count in counts.values():
        denominator *= factorial(count)
    return factorial(len(combination)) // denominator

# 参数
n = 12
k = 4

# 找到所有组合
combinations = find_solutions(n, k)
combinations_list = sorted(combinations)

print(f"Total number of unique combinations: {len(combinations_list)}")
print("Combinations:")
for combination in combinations_list:
    print(combination)

# 计算每个组合的排列数
permutation_counts = [count_permutations(comb) for comb in combinations_list]

# 生成输出表达式
output_parts = [f"{count}x{permutation_counts.count(count)}" for count in set(permutation_counts)]

# 计算总排列数
total_permutations = sum(permutation_counts)

output_expression = " + ".join(output_parts)

print(f"\nTotal number of unique solutions: {total_permutations}")
print("Detailed calculation:")
print(output_expression)

print("\nEach combination with its permutation count:")
for combination, perm_count in zip(combinations_list, permutation_counts):
    print(f"{combination} - {perm_count} permutations")

# 创建条形图展示每个组合及其排列数
plt.figure(figsize=(15, 8))
x_labels = [str(combination) for combination in combinations_list]
y_values = permutation_counts

plt.barh(x_labels, y_values, color='skyblue')
plt.xlabel('排列数')
plt.ylabel('组合')
plt.title('每个组合的排列数')
plt.grid(axis='x', linestyle='--', alpha=0.7)
for index, value in enumerate(counts):
    plt.text(value, index, str(value))
plt.tight_layout()

# 保存为图片
plt.savefig('permutation_counts.png', dpi=300, bbox_inches='tight')
plt.show()

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/724058.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【UIDynamic-动力学-UICollisionBehavior-碰撞行为-4个代理方法 Objective-C语言】

一、接下来,我们来说这个碰撞的代理方法, 1.我们把之前的代码再来复制一份儿,改个名字:07-碰撞行为-代理, 首先,在这个Collision里边,它有一个代理,我们找到这个行为,UICollisionBehavior,点进来看一下, 点进来, 在最下边,有一个delegate, 这个delegate,叫做UIC…

数据结构之探索“队列”的奥秘

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:数据结构(Java版) 目录 队列有关概念 队列的使用 队列模拟实现 循环队列的模拟实现 622. 设计循环队列 双端队…

仓库管理系统的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,公告管理,物资管理,基础数据管理,用户管理 用户账户功能包括:系统首页,个人中心,公告管理,物…

【python】PyCharm如何设置字体大小和背景

目录 效果展示 字体大小 背景设置 效果展示 字体大小 再左上角找到四条杠的图标 找到File 一般字体大小为22最合适,行间距为默认 背景设置 还是再字体设置的页面搜索 background 小编的其他文章详见,欢迎来支持 东洛的克莱斯韦克-CSDN博客 【机器…

failed to create network xxxx: Error response from daemon

问题描述: 启动项目时,docker内部网络冲突。 解决方案: 1.删除所有docker容器(强制删除一个或多个容器,即使它们正在运行) docker rm -f $(docker ps -aq) 2.验证docker容器是否删除成功 docker ps --…

“论数据访问层设计技术及其应用”写作框架,系统架构设计师

论文真题 在信息系统的开发与建设中,分层设计是一种常见的架构设计方法,区分层次的目的是为了实现“高内聚低耦合”的思想。分层设计能有效简化系统复杂性,使设计结构清晰,便于提高复用能力和产品维护能力。一种常见的层次划分模…

Google Adsense----Wordpress插入谷歌广告

1.搭建个人博客,绑定谷歌search consol,注册adsense 详细可以参考这个视频b站视频 2.将个人博客网站关联到Adsense 在adsense里新加网站,输入你的博客网址,双击网站 将这段代码复制到header.php的里面 在wordpress仪表盘的外观-主题文件编辑器,找到header.php将代码复制,…

C++跨平台socket编程

C跨平台socket编程 一、概述1.1 TCP协议1.1 TCP 的主要特性1.2 TCP报文格式 UDP报文格式IP协议使用windows编辑工具直接编辑Linux上代码 二、系统socket库1.windows上加载socket库2.创建socket2.1 windows下2.2 linux下 3.网络字节序4.bind端口5.listen监听并设置最大连接数6.a…

【Python机器学习实战】 | Lasso回归和弹性网回归详细分析研究

🎩 欢迎来到技术探索的奇幻世界👨‍💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介: C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &…

【windows|004】BIOS 介绍及不同品牌电脑和服务器进入BIOS设置的方法

🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 ​ 🏅阿里云ACE认证高级工程师 ​ 🏅阿里云开发者社区专家博主 💊交流社…

【BEV】BEVFormer总结

本文分享BEV感知方案中,具有代表性的方法:BEVFormer。 它基于Deformable Attention,实现了一种融合多视角相机空间特征和时序特征的端到端框架,适用于多种自动驾驶感知任务。 主要由3个关键模块组成: BEV Queries Q&am…

【qt5生成软件-can卡-上位机-无法加载ControlCAN.dll错误代码(0xc0150002)等相关问题-WIN11系统-尝试解决】

【qt5生成软件-无法加载ControlCAN.dll&错误代码0xc0150002:-等相关问题-WIN11系统-尝试解决-总结整理】 1.前言2.环境说明3.问题说明4.尝试方法总结(1)更新支持包c库(2)更新USB相关驱动(3)…

安装pytorch环境

安装:Anaconda3 通过命令行查显卡nvidia-smi 打开Anacanda prompt 新建 conda create -n pytorch python3.6 在Previous PyTorch Versions | PyTorch选择1.70,安装成功,但torch.cuda.is_available 返回false conda install pytorch1.7.0…

【golang学习之旅】使用VScode安装配置Go开发环境

1. 下载并安装Go1.1 下载地址1.2 选择版本并下载1.3 安装目录1.4 验证是否安装成功 2. 配置环境变量2.1 配置步骤2.2 GO部分环境变量说明 3. 下载或更新 Vscode3.1 下载地址3.2 安装步骤 4. 为Go开发配置VScode 1. 下载并安装Go 1.1 下载地址 https://studygolang.com/dl 1.…

【单片机】三极管的电路符号及图片识别

一:三极管的电路符号 二:三极管的分类 a;按频率分:高频管和低频管 b;按功率分:小功率管,中功率管和的功率管 c;按机构分:PNP管和NPN管 d;按材质分:硅管和锗管 e;按功能分:开关管和放…

硬盘分区无法访问:深度解析与解决之道

一、硬盘分区无法访问的现象描述 在日常使用电脑的过程中,有时会遇到硬盘分区无法访问的情况。这通常表现为双击分区时系统提示“无法访问”、“磁盘未格式化”或“需要格式化”等错误消息,导致分区内的文件无法读取或操作。这种情况可能会给用户带来极…

构建高效、便捷的家校沟通桥梁

在现代教育中,家校之间的有效沟通和协作是确保学生全面发展的关键。搭贝家校管理应用通过一系列强大而便捷的功能,帮助学校和家长实现无缝对接,提供全面的管理和服务。以下是搭贝家校管理应用的主要功能和优势。 🏫 主要功能模…

发布自己的c#包到nuget

1)创建自己的nuget账号 NuGet Gallery | Home 2)在Rider中-->项目文件夹右键-->properties 注意:必须勾选生成nuget包 3)编译后,将生成一个包 4)点击上传包 5)将之前的nuget包拖拽过来,点击上传即可,如果有不对的比如&a…

STM32开发环境搭建

新建工程 1.双击桌面的快捷方式打开STM32CubeIDE,需要选择一下工作空间,保存路径可以根据实际选择其他路径(不要带中文)。 点击File->New->STM32 Project. 搜索并选择芯片,我这里以STM32F103RCT6为例&#xff0…