点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

沙场烽火连胡月,海畔云山拥蓟城。

大家好,我是Python进阶者。这篇文章的题目真的是很难取,索性先取这个了,装个13好了。

前言

前几天在才哥交流群里,有个叫【Rick Xiang】的粉丝在Python交流群里问了一道关于排列组合的问题,初步一看觉得很简单,实际上确实是有难度的。

题目是:一个列表中有随机15个数,没有重复值。从列表里面任意选5个数,如何选出来包含a, a+1的所有组合。a可以是15个数中的任意一个。

一、思路

这个问题看似简单,思路正如上图的【张老师】说的那样,分两步走,理论上来说,确实是可以实现。正常我们计算排列组合公式,用下图中的组合公式计算是没问题的。

但是这道题目的实现,涉及到用Python程序进行实现,当然计算一个数值,对于Python和我们来说并不难,难的是需要回归排列组合原本的状态,然后用程序进行实现。本文借用了群成员【有点意思】所说的蒙特卡洛算法和代码进行实现,下面一起来看看吧!

    这里引用【张老师】提及的第二种方案,先随机取14个数,然后从14个随机数中随机取一个,然后自增1,作为第15个随机数,之后再从这15个随机数中进行随机取5个随机数,再进行if判断,看看连续值是否同时存在同一个列表中,之后把满足条件的列表append到一个空列表中去,最后再去用set集合去重,得到最后的结果。

二、解决方法

1)伪代码

这里先给出【有点意思】大佬的伪代码,这样看上去大家也更加好理解一些,如下图所示。其实下面这个代码也不算是伪代码,现在Python也支持中文变量,下面这个代码也是完全可以跑起来的,只不过看上去要比下文中的纯英文代码要更加好理解一些。

下面给出具体的实现过程,这里给出5份代码,欢迎大家积极尝试。

2)代码一

# coding: utf-8
import randomdef quchong(list_data):list2 = []for i in list_data:if i not in list2:list2.append(i)return list2# 从随机的15个数值中随机取出5个数,放到一个数组
# 生成不重复的14个随机数
random_14 = [random.randint(0, 100) for i in range(14)]  # 这个写法容易出现随机值重复
random_14 = random.sample(range(100), 14)
print(random_14)
random_1 = random.choice(random_14)
random_2 = random_1 + 1
random_14.append(random_2)
random_15 = random_14
print(random_1, random_2)final_list = []
for i in range(100):select = [random.choice(random_15) for j in range(5)]quchong_select = set(select)if random_1 in quchong_select and random_2 in quchong_select:final_list.append(quchong_select)
fina_result = quchong(final_list)
print(len(fina_result))

乍一看,这个方法确实可以实现,但是这里会有一个小bug,那就是random.randint()函数生成的随机中会有重复值,而题目要求是生成不重复的随机值。那么这个问题,将在代码二中得到解决。

3)代码二

使用random.sample()函数,这个函数可以随机产生随机值,而且不会重复,还是很奈斯的。另外,使用了numpy.random.choice()函数,可以直接选择随机的5个数,效率比代码一更高一些。

# -*- coding: utf-8 -*-
import numpy as np
import randomdef quchong(list_data):list2 = []for i in list_data:if i not in list2:list2.append(i)return list2# 从随机的15个数值中随机取出5个数,放到一个数组
# 生成不重复的14个随机数
random_14 = random.sample(range(100), 14)
print(random_14)
random_1 = random.choice(random_14)
random_2 = random_1 + 1
random_14.append(random_2)
random_15 = random_14
print(random_1, random_2)final_list = []
for i in range(100):sub_random_data = np.random.choice(random_15, 5)quchong_select = set(sub_random_data)if random_1 in quchong_select and random_2 in quchong_select:final_list.append(quchong_select)
fina_result = quchong(final_list)
print(len(fina_result))

4)代码三

代码三主要是在代码一和代码二的基础上加了一些函数,使得读起来更加的有逻辑性和层次感。

# -*- coding: utf-8 -*-
# 模块化
import random
import numpy as np# 从随机的15个数值中随机取出5个数,放到一个数组,生成不重复的14个随机数
def get_random15():random_14 = random.sample(range(1000), 14)print(random_14)random_1 = random.choice(random_14)random_2 = random_1 + 1random_14.append(random_2)random_15 = random_14print(random_1, random_2)get_final_result(random_1, random_2, random_15)def get_final_result(random_1, random_2, random_15):final_list = []for i in range(1000):sub_random_data = np.random.choice(random_15, 5)quchong_select = set(sub_random_data)if random_1 in quchong_select and random_2 in quchong_select:final_list.append(quchong_select)fina_result = quchong(final_list)print(len(fina_result))def quchong(list_data):list2 = []for i in list_data:if i not in list2:list2.append(i)return list2if __name__ == '__main__':get_random15()

5)代码四

细心的朋友可能已经发现了一个问题,在随机从np.random.choice(random_15, 5)取值的时候,也会取出重复的值,这样也是不符合要求的,这里给出了一个方案,从15个随机数中取出一个之后,然后remove掉这个取出的数,重新去剩下的列表中去取,这样就完美的避开了这个问题。

# 模块化
import random
import numpy as np# 取出随机的15个数值
def get_random15():for i in range(2):random_15 = random.sample(range(20), 15)# print(random_15)get_random5(random_15)# 遍历随机的15个数值,取相邻的两个随机数,并调用函数进行处理
def get_random5(random_15):random_5 = []# 遍历5次,从random_15中取5个不同的元素for i in range(5):random_data = np.random.choice(random_15)random_5.append(random_data)random_15.remove(random_data)# print(random_5)for num in random_5:random_1 = numrandom_2 = random_1 + 1get_final_result(random_1, random_2, random_5)# 判断相邻的两数值是否同时存在随机的15个数值的列表中,如果满足要求,就存到一个列表中,并调用去重函数
def get_final_result(random_1, random_2, random_5):final_list = []if random_1 in random_5 and random_2 in random_5:print(random_5)final_list.append(random_1)result = quchong(final_list)print(result)# 针对得到的所有列表,进行去重处理
def quchong(list_data):list = []for i in list_data:if i not in list:list.append(i)return listif __name__ == '__main__':get_random15()

代码写到这里,已经比之前的方案要好很多了,比之前的三个代码都要严谨一些,但是仍然存在不足。虽然解决了随机生成重复性的问题,也解决了随机从random_15中取出重复数的问题,但是弊端还是存在的。这个代码遍历挺多的,复杂度倒是正常,但是输出的格式不太好看,没有达到预期。这里我只是遍历了2次,而且随机数我只是开放到0-20,如果循环次数增多,数值越多的话,计算起来速度可就不好说了。

6)代码五

经过【有点意思】大佬和我的共同努力,现在祭出终极版本,这个版本是迄今为止,针对该问题写出的最严谨的一个版本了,代码如下。

# -*- coding: utf-8 -*-
# 模块化
import random
import numpy as np
import time# 取出随机的15个数值
def get_random15():for i in range(100000):random_15 = random.sample(range(2000), 15)# print("随机15数=",random_15,len(random_15))get_random5(random_15)# 遍历随机的15个数值,取相邻的两个随机数,并调用函数进行处理
def get_random5(random_15):random_5 = []# 遍历5次,从random_15中取5个不同的元素for i in range(5):random_data = np.random.choice(random_15)random_5.append(random_data)random_15.remove(random_data)# print("random_5=",random_5)# print("random_15=",random_15)for num in random_5:random_1 = numrandom_2 = random_1 + 1# print(random_1,random_2)get_final_result(random_1, random_2, random_5)# 判断相邻的两数值是否同时存在随机的15个数值的列表中,如果满足要求,就存到一个列表中,并调用去重函数
def get_final_result(random_1, random_2, random_5):final_list = []if random_1 in random_5 and random_2 in random_5:# print(random_5)final_list.append(random_5)result = quchong(final_list)    if result:        if len(result[0]) == 5:# print(random_1,random_2)# print("result=",result)final_result.append(result)# 针对得到的所有列表,进行去重处理
def quchong(list_data):list = []for i in list_data:if i not in list:list.append(i)return listif __name__ == '__main__':start_time = time.time()global final_resultfinal_result = []get_random15()final_result = quchong(final_result)print("共%d个符合题意的列表" % len(final_result))print("分别是:%s" % final_result)end_time = time.time()used_time = end_time - start_timeprint()print("本次程序用时:{}".format(time.strftime('%H(小时):%M(分钟):%S(秒)', time.gmtime(used_time))))

这个代码运行之后,可以看到符合题意列表的具体个数,还有具体的列表数值,还有耗时时间。

经过测试,在10万次循环以内,符合要求的数据大概有1000左右,运行时间也只是秒级的。如果继续扩大循环力度,程序的复杂度会更加大,更加贴近理论的排列组合值,因为耗时太长,这里不再做测试,感兴趣的话,自己可以改下参数进行调试。

三、总结

我是Python进阶者。本文基于粉丝针对排列组合问题的提问,给出了一个利用Python基础+蒙特卡洛算法的解决方案,基本上可以达到了粉丝的要求。

不过话说回来,这个方案还是存在一定的弊端的,随着循环次数越多,随机数越大,排列组合数就会越多,运行的时间也就会越长,当然得到的数据也就更加的精准了。

最后感谢【Rick Xiang】提问,感谢【张老师】提供的思路,感谢【有点意思】大佬一直和我探讨交流学习,这一过程,虽然耗时,但是也是学到了很多知识,也感谢我寄几花时间和经历整理这篇接近4000字的文章。

针对这个问题,小编这里整理了1个思路,当然实现方法肯定远远不只是这1种,如果你有其他的方法,可以随时分享给我噢!

小伙伴们,快快用实践一下吧!如果在学习过程中,有遇到任何问题,欢迎加我好友,我拉你进Python学习交流群共同探讨学习。

------------------- End -------------------

往期精彩文章推荐:

  • Python中encode和encoding的区别是什么?

  • 手把手教你使用openpyxl库从Excel文件中提取指定的数据并生成新的文件(附源码)

  • 手把手教你用Python来模拟绘制自由落体运动过程中的抛物线(附源码)

  • 盘点3种Python网络爬虫过程中的中文乱码的处理方法

欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持

想加入Python学习群请在后台回复【入群

万水千山总是情,点个【在看】行不行

/今日留言主题/

随便说一两句吧~~

分享一道用Python基础+蒙特卡洛算法实现排列组合的题目(附源码)相关推荐

  1. python画圣诞帽_使用Python给头像加上圣诞帽或圣诞老人小图标附源码

    随着圣诞的到来,想给给自己的头像加上一顶圣诞帽.如果不是头像,就加一个圣诞老人陪伴. 用Python给头像加上圣诞帽,看了下大概也都是来自2017年大神的文章:https://zhuanlan.zhi ...

  2. python画圣诞老人_使用Python给头像加上圣诞帽或圣诞老人小图标附源码

    随着圣诞的到来,想给给自己的头像加上一顶圣诞帽.如果不是头像,就加一个圣诞老人陪伴. 用Python给头像加上圣诞帽,看了下大概也都是来自2017年大神的文章:https://zhuanlan.zhi ...

  3. 分享一款超40款多功能工具箱组合微信小程序源码_支持流量主,聚集市面上大部分功能的小程序,无需服务器和域名!源码拿去!

    分享一款超多功能工具箱组合微信小程序源码_支持流量主,无需服务器和域名!适合小白操作! 简介: 超多功能工具箱组合微信小程序功能实用性质特别的高,用户还能覆盖的广一些具体功能列表如下: 1.证件照制作 ...

  4. 基础入门-算法逆向散列对称非对称JS源码逆向AESDESRSASHA

    文章目录 安全测试中: 加密解密-识别特征&解密条件 其他密文特点见: 解密实例-密文存储&数据传输 课件附加资源百度云 安全测试中: 密文-有源码直接看源码分析算法(后端必须要有源码 ...

  5. Python采集天气数据,做可视化分析【附源码】

    知识点: 动态数据抓包 requests发送请求 结构化+非结构化数据解析 开发环境: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 requests 如果安装python ...

  6. Python实现的图书分析大屏展示系统(附源码)

    今天给大家分享的是基于 Flask.Echarts.Pandas 等实现的图书分析大屏展示系统. 项目亮点 采用 pandas.numpy 进行数据分析 基于 snownlp.jieba 进行情感分析 ...

  7. Python制作经典游戏案例-水果忍者(附源码等文件)

    目录 前言 代码展示 总结 前言 大家好,我是辣条哥,今天给大家分享一款我以前特爱玩的游戏,水果大战,今天我就教大家使用python把这款游戏制作出来.我们先来看效果 点击跳转文末 相关的一些音乐文件 ...

  8. python创意游戏-Python制作十款经典的童年游戏(附源码)

    不知道行友们每年六一是怎么度过的,行哥的童年是在游戏世界里度过.这里行哥分享一下十个python可以制作的经典游戏,看看有没有你的菜,代码链接放在文末 对了以下游戏皆是小学六年级的代码水平 如有不适, ...

  9. Python基于民航业知识图谱的自动问答系统(附源码)

    一.开发环境 Windows 10 x64 Python 3.7 Neo4j community 3.5.20 二.项目运行 1.确保安装所需依赖 pip install -r requirement ...

  10. python 实现模拟鼠标点击器 可运行 附源码

    工具下载链接(网盘) https://pan.baidu.com/s/1GIZPHQnRQqTD5h1Cy70MNQ?pwd=kxzz 一.前言: 对于一些比较肝的游戏,想要使用工具挂机: 对于一些购 ...

最新文章

  1. Linux常用命令手册
  2. SIP术语的名词解析
  3. R语言使用lm构建线性回归模型、并将目标变量对数化(log10)实战:可视化模型预测输出与实际值对比图、可视化模型的残差、模型预测中系统误差的一个例子 、自定义函数计算R方指标和均方根误差RMSE
  4. R语言length函数计算向量、列表、字符串长度实战
  5. SAP WM 针对采购订单收货时候不能自动获取物料主数据里的Special Movement Indicator?
  6. 测试php连接mysql
  7. WINCE6.0操作系统---内核(kernel)学习
  8. TCP/IP模型如何分层?路由器、网卡分别属于哪一层?
  9. ABP源码分析二十五:EventBus
  10. 如何写出让同事膜拜的漂亮代码?
  11. 2018-2019-1 20165309 《信息安全系统设计基础》第一周学习总结
  12. 海康威视ip摄像头通过网线直接连接笔记本电脑使用
  13. Spring核心包介绍
  14. t-SNE原理与推导
  15. android手机碎片管理,android手机需要进行磁盘碎片整理么
  16. 钉钉考勤接口python3.6调用
  17. mac重装系统之后删除容器中的其他卷宗内容
  18. 计算机键盘可以分为哪几个区,键盘分为哪几个区?分别是什么?
  19. 项目没有亮点,如何应对面试官的提问?
  20. unity读写Excel

热门文章

  1. 树莓派安装第三方操作系统
  2. 历史时点数据统计如何设计表结构_如何做好调薪管理?年度调薪的操作方式
  3. java毕业设计民航售票管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
  4. Android崩溃治理
  5. 一.什么是java面向对象 (小白神器)
  6. 太湖之光超级计算机应用最高奖,“神威·太湖之光”两项应用入围“戈登·贝尔”奖...
  7. MEPR500+电子护照阅读器|识读模块嵌入式安装与应用说明
  8. Structed Streaming(Continuous Processing报错):StreamingQueryException;java.util.NoSuchElementException
  9. excel汇总软件如何快速汇总多个表格数据
  10. 使用hexo+icarus快速搭建属于自己的博客网站