用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线程池的实现实例
Nov 18 Python
python将MongoDB里的ObjectId转换为时间戳的方法
Mar 13 Python
Python爬虫爬取美剧网站的实现代码
Sep 03 Python
Python3中类、模块、错误与异常、文件的简易教程
Nov 20 Python
python求最大连续子数组的和
Jul 07 Python
对numpy中向量式三目运算符详解
Oct 31 Python
celery4+django2定时任务的实现代码
Dec 23 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
Mar 18 Python
PyQt5创建一个新窗口的实例
Jun 20 Python
PyQt 图解Qt Designer工具的使用方法
Aug 06 Python
python使用nibabel和sitk读取保存nii.gz文件实例
Jul 01 Python
PyCharm上安装Package的实现(以pandas为例)
Sep 18 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通用防注入程序 推荐
2011/02/26 PHP
coreseek 搜索英文的问题详解
2013/06/08 PHP
深入array multisort排序原理的详解
2013/06/18 PHP
php实现文件下载代码分享
2014/08/19 PHP
PHP高手需要要掌握的知识点
2014/08/21 PHP
jqPlot Option配置对象详解
2009/07/25 Javascript
不用锚点也可以平滑滚动到页面的指定位置实现代码
2013/05/08 Javascript
IE网页js语法错误2行字符1、FF中正常的解决方法
2013/09/09 Javascript
javascript中setTimeout和setInterval的unref()和ref()用法示例
2014/11/26 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
2015/09/27 Javascript
简单实现的JQuery文本框水印插件
2016/06/14 Javascript
浅谈js数组和splice的用法
2016/12/04 Javascript
ES6通过babel转码使用webpack使用import关键字
2016/12/13 Javascript
vue实现word,pdf文件的导出功能
2018/07/31 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
如何在Vue中使用CleaveJS格式化你的输入内容
2018/12/14 Javascript
微信小程序使用for循环动态渲染页面操作示例
2018/12/25 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
原生JavaScript实现刮刮乐
2020/09/29 Javascript
vue 实现基础组件的自动化全局注册
2020/12/25 Vue.js
[01:13:59]LGD vs Mineski Supermajor 胜者组 BO3 第三场 6.5
2018/06/06 DOTA
python sqlobject(mysql)中文乱码解决方法
2008/11/14 Python
跟老齐学Python之Python安装
2014/09/12 Python
Python 文件管理实例详解
2015/11/10 Python
python 网络爬虫初级实现代码
2016/02/27 Python
如何基于Python创建目录文件夹
2019/12/31 Python
Pycharm最新激活码2019(推荐)
2019/12/31 Python
Flask中sqlalchemy模块的实例用法
2020/08/02 Python
Python限制内存和CPU使用量的方法(Unix系统适用)
2020/08/04 Python
学校安全教育月活动总结
2014/07/07 职场文书
党委班子对照检查材料
2014/08/19 职场文书
作文评语怎么写
2014/12/25 职场文书
预防职务犯罪警示教育心得体会
2016/01/15 职场文书
《秋天的怀念》教学反思
2016/02/17 职场文书
MySQL索引失效的典型案例
2021/06/05 MySQL
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python