用Python解决计数原理问题的方法


Posted in Python onAugust 04, 2016

前几天遇到这样一道数学题:

用四种不同颜色给三棱柱六个顶点涂色,要求每个点涂一种颜色,且每条棱的两个端点涂不同颜色,则不同的涂色方法有多少种?

用Python解决计数原理问题的方法

当我看完题目后,顿时不知所措。于是我拿起草稿纸在一旁漫无目的地演算了一下,企图能找到解决方法。结果一无所获。于是打算通过程序算法解决这个问题。经过2个多小时的研究,终于完成了代码,并求得了答案。

由于Python写起来比较方便而且本人比较喜欢Python的语法,所以研究算法时我通常采用Python,此次也不例外。以下就是整个算法的实现过程。

两种算法

我一共想出了两种用于解决本题的算法:

    算法一:将所有的涂色情况通过程序的循环计算出来,然后通过程序的条件判断去除掉不合题意的所有情况,最后得到最终结果。

    算法二:从其中任意一个端点(p0)入手,由于其它所有端点都没有涂色,所以它可以涂四种颜色。将这四种颜色通过循环分别涂在这个端点上,每涂上一种颜色后,获取与它相临的一个端点(p1),并获取它可以涂上的颜色,然后通过循环将可用颜色涂上(及不能涂上与p0相同的颜色),每涂上一种颜色,又将p1相邻的未涂色的点涂色(及除p0外其他的相邻端点)。每个点被涂色后都采用同样的方法将相邻的点涂色,以此类推,涂完最后一个点,就记一次情况。所有的递归都完成后,就获得了所有情况。

算法一很直接很粗暴,所以我采用了算法二来解决上述问题。接下来就是具体的代码了。

算法实现

我写了大约90行Python代码来实现这个算法:

colorList = [0, 1, 2, 3]
pointList = []
amount = 0


class Point(object):
  def __init__(self):
    super(Point, self).__init__()

    self.neibors = []
    self.color = None

  def paint(self, c):
    self.color = c

  def clean(self):
    self.color = None

  def getLeftOverColors(self):
    copyOfColorList = colorList[0 : 4]

    for neibor in self.neibors:
      nc = neibor.color

      if nc in copyOfColorList:
        copyOfColorList.remove(nc)

    return copyOfColorList


def main():
  global pointList

  p0 = Point()
  p1 = Point()
  p2 = Point()
  p3 = Point()
  p4 = Point()
  p5 = Point()

  p0.neibors = [p1, p2, p4]
  p1.neibors = [p0, p2, p5]
  p2.neibors = [p0, p1, p3]
  p3.neibors = [p2, p4, p5]
  p4.neibors = [p0, p3, p5]
  p5.neibors = [p4, p3, p1]

  pointList = [p0, p1, p2, p3, p4, p5]

  paintPoint(p0)

  print(amount)

def paintPoint(p):
  global amount

  colors = p.getLeftOverColors()
  lastOne = isLastOne()

  for c in colors:
    p.paint(c)

    if lastOne:
      amount += 1
    else:
      for currentNeibor in p.neibors:
        if currentNeibor.color == None:
          paintPoint(currentNeibor)

          break

  p.clean()

def isLastOne():
  global pointList

  paintedNum = 0

  for p in pointList:
    if p.color != None:
      paintedNum += 1

  return paintedNum == 5


if __name__ == "__main__":
  main()

以下是对各段代码的介绍。

全局变量

    colorList:颜色列表

    pointList:存放六个点的列表

    amount : 涂色方案的种数

Point类

用于储存各个点的信息,如点的颜色(color属性,None代表无颜色)、相邻的点('neibors'属性)。以及提供paint方法用于将点标记颜色;clean方法用于去除颜色;getLeftOverColors方法用于获取可用颜色,及获取相邻点没有使用的颜色。

main函数

程序开始运行时调用的函数,其中构造了所需的六个点,以及分别为这六个点明确了相邻的三个点。注意,由于这里的点只有相邻和不相邻的位置关系,所以不需要在意这些点到底在三棱柱里对应哪个位置,任意设定这些点的位置对结果来说并没有影响,只需注意它们之间的相邻关系即可。

isLastOne函数

判断是不是最后一个未涂色的点。

paintPoint函数

用于对作为参数传入的点进行着色。其中首先通过调用该点的getLeftOverColors方法获取可用颜色,然后按照上文算法中介绍的,通过遍历可用颜色列表,为该点着色,如果该点不是最后一个点(通过isLastOne函数判断),就递归调用paintPoint函数为相邻的一个未着色的点着色,如果是,则将记下一次涂色方案。

运行代码,得到结果 - 264:

用Python解决计数原理问题的方法

Ok,于是这道题就在我们的计算机的帮助下,被成功解决掉了~如果大家有更好的方案解决这一算法问题,欢迎留言进行交流~希望本文对大家学习Python和计数原理都能有所帮助。

Python 相关文章推荐
python使用xlrd实现检索excel中某列含有指定字符串记录的方法
May 09 Python
Python基于Tkinter的HelloWorld入门实例
Jun 17 Python
利用numpy实现一、二维数组的拼接简单代码示例
Dec 15 Python
Python中单例模式总结
Feb 20 Python
使用Python实现在Windows下安装Django
Oct 17 Python
PyTorch 随机数生成占用 CPU 过高的解决方法
Jan 13 Python
使用Puppeteer爬取微信文章的实现
Feb 11 Python
Python 字典中的所有方法及用法
Jun 10 Python
python用tkinter实现一个gui的翻译工具
Oct 26 Python
用python批量移动文件
Jan 14 Python
pycharm 使用anaconda为默认环境的操作
Feb 05 Python
pytorch 如何使用amp进行混合精度训练
May 24 Python
快速入手Python字符编码
Aug 03 #Python
Python采用Django制作简易的知乎日报API
Aug 03 #Python
利用Python实现图书超期提醒
Aug 02 #Python
Python正规则表达式学习指南
Aug 02 #Python
Python实现SMTP发送邮件详细教程
Mar 02 #Python
python logging 日志轮转文件不删除问题的解决方法
Aug 02 #Python
python中的字典使用分享
Jul 31 #Python
You might like
PHP支持多种格式图片上传(支持jpg、png、gif)
2011/11/03 PHP
PHP中STDCLASS用法实例分析
2016/11/11 PHP
PHP运用foreach神奇的转换数组(实例讲解)
2018/02/01 PHP
通过判断JavaScript的版本实现执行不同的代码
2010/05/11 Javascript
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
jQuery截取指定长度字符串的实现原理及代码
2014/07/01 Javascript
js实现文本框宽度自适应文本宽度的方法
2015/08/13 Javascript
nodejs创建web服务器之hello world程序
2015/08/20 NodeJs
js根据手机客户端浏览器类型,判断跳转官网/手机网站多个实例代码
2016/04/30 Javascript
JS函数多个参数默认值指定方法分析
2016/11/28 Javascript
Vue.js开发环境快速搭建教程
2017/03/17 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
2018/09/20 jQuery
手把手教你使用TypeScript开发Node.js应用
2019/05/06 Javascript
Vue的生命周期操作示例
2019/09/17 Javascript
async/await让异步操作同步执行的方法详解
2019/11/01 Javascript
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
关于better-scroll插件的无法滑动bug(2021通过插件解决)
2021/03/01 Javascript
[02:44]DOTA2英雄基础教程 克林克兹
2014/01/15 DOTA
python中的字典详细介绍
2014/09/18 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
python使用Apriori算法进行关联性解析
2017/12/21 Python
django+tornado实现实时查看远程日志的方法
2019/08/12 Python
关于matplotlib-legend 位置属性 loc 使用说明
2020/05/16 Python
Lookfantastic葡萄牙官方网站:欧洲第一大化妆品零售商
2018/03/17 全球购物
Electrolux伊莱克斯巴西商店:家用电器、小家电和配件
2018/05/23 全球购物
大一自我鉴定范文
2013/10/04 职场文书
上课迟到检讨书
2014/01/19 职场文书
《大海那边》教学反思
2014/04/09 职场文书
企业办公室主任岗位职责
2015/04/01 职场文书
道歉短信大全
2015/05/12 职场文书
2015年酒店年度工作总结
2015/05/23 职场文书
秋菊打官司观后感
2015/06/03 职场文书
解决Django transaction进行事务管理踩过的坑
2021/04/24 Python
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js