排列组合——排列公式的推理和组合

加法原理和乘法原理,是排列组合中的二条基本原理,在解决计数问题中经常运用。掌握这两条原理,并能正确区分他们,至关重要。

加法原理

若完成一件事情有3类方式,其中第一类方式有1种方法,第二类方式有3种方法,第三类有2种方法,这些方法都不相同,但任选一种方法都可以完成此事,则完成这件事情共有1+3+2=6种方法,这一原理称为加法原理。
例如:从甲地到乙地有三类方式,一是汽车,二是火车,三是飞机。若一天中汽车有2班,火车有4班,飞机有一班,那么从甲地到乙地共有多少种不同的走法。共有2+4+1=7种。

乘法原理

若完成一件事情分r个步骤,其中第一个步骤有m1种方法,第二个步骤有m2种方法……第步骤共有mr种方法,各步骤连续或同时完成,这件事才算完成,则完成这件事共有m1*m2*……*mr种方法。
例如:从甲地到丙地必须经过乙地。从甲地到乙地有4条路线,从乙地到丙地有3条路线,问从甲地到丙地共有多少种不同的走法?
解:要从甲地到达丙地,必须经过两个步骤:先从甲地到乙地,有4条路线;再从乙地到丙地,有3条路线。只有这两个步骤都完成了,才能完成这种事情,缺少哪一个步骤都不行。因此从甲地到丙地共有4*3=12种走法。

加法原理和乘法原理的区别

以上两个基本原理在排列组合问题中将会反复使用。这两个原理回答的都是关于完成一件事情的不同方法的种数问题,但是又有根本区别。加法原理针对的是“分类”问题,若完成一件事情有多类方式,每一类方式的各种方法相互独立,用其中任何一种方法都可以完成这件事情,则用加法原理;而乘法原理针对的是“分步”问题,若完成一件事情必须依次经过多个步骤,每一个步骤的各种方法相互依存,只有各种步骤都完成才算做完成这种事情,则这时用乘法原理

排列数公式推理过程

例:用1、2、3这3个数字可以组成多少个数字十位和个位不重复的两位数?
解:要组成数字不重复的两位数,需要经过两个步骤:第一步确定十位上的数,数字1、2、3都可以放在十位上,共有3种方法;第二步确定个位上的数,因为要求个位数与十位数不能重复,所以个位上的数,只能从三个数字中去掉十位数后所剩的两个数字中任选一个,共有2种方法。只有十位和个位上的数都确定了,才能组成数字不重复的两位数,这两个步骤缺少哪一个都不行。因此,根据乘法原理,3*2=6.

上例中,我们把数字1、2、3称为元素。组成数字不重复的两位数这个问题,从3个不同的元素中任取2个,然后按顺序排成一列数,由于这样的排列与数字不重复的两位数是一一对应的,因此求数字不重复的两位数的个数等同于求这样的排列个数。

推理过程:从n个不同元素中取出m个不同元素排成一列,必须经过m个步骤。
第一步,确定第1个位置上的元素,可以从这n个元素中任取1个放在这个位置上,共有n种方法,即n-(1-1)括号内为位置数减1;
第二步,确定第2个位置上的元素,可以从剩下的n-1个元素中任取1个放在这个位置上,共有n-1种方法,即n-(2-1);
……
第m步,确定第m位置上的元素,第m位置上的元素从剩下的n-(m-1)个元素中任选一个,共有n-m+1种方法。根据乘法原理,全部确定这m个位置的元素共有n(n-1)(n-2)……*(n-m+1)种方法。由于一种方法对应一个排列,所以所有这样排列的个数即排列数。

不可重复排列数公式.png
组合

排列是一个与次序有关的概念,如12,21这两个数字是两个不同的排列,但是在组合里,12和21是一个意思,因为12和21都是由1和2组合而成的,所以顺序并不会影响对组合的判断,因此,组合是与排列概念不同的问题。

从n个不同的元素中,每次取出m个(m<=n)不同元素,不考虑顺序组成一组,叫做从n个元素中每次取出m个元素的组合。这样得出的组合个数称为组合数,记作C (n,m)

求从n个不同元素中取出m个元素的排列数A(n,m),可以按以下两个步骤进行:
第一步,求出这n个不同元素中取出m个元素的组合数C (n,m),
第二步,求出每一个组合中m个元素的全排列数A(m,m),根据乘法原理得出,A(n,m)=C (n,m)*A(m,m),可重复组合公式:C (n,m)=A(n,m)/A(m,m)=n!/m!(n-m)!,
不可重复组合公式:C (n,m)=(m+n-1)!/(m!(n-1)!)
对于实际问题,必须正确判别是排列问题还是组合问题,其区别的关键在于要不要将所取出的元素进行排队。若要排队,则是排列问题,若不要排队,则是组合问题。
以下为组合数计算器python代码。
#!/usr/bin/env python3
# -
- coding: utf-8 -*-

import math
from tkinter import *
class Window:
    def __init__(self, title='组合数计算器', width=300, height=120, staFunc=bool, stoFunc=bool):
        self.w = width
        self.h = height
        self.stat = True
        self.staFunc = staFunc
        self.stoFunc = stoFunc
        self.staIco = None
        self.stoIco = None

        self.root = Tk(className=title)

    def drawCenter(self):
        ws = self.root.winfo_screenwidth()#用户屏幕宽度
        hs = self.root.winfo_screenheight()#用户屏幕高度
        x = int( (ws/2) - (self.w/2) )#距屏幕左边框的像素点数
        y = int( (hs/2) - (self.h/2) )#距屏幕上边框的像素点数
        self.root.geometry('{}x{}+{}+{}'.format(self.w, self.h, x, y))
    
    def createWidgets(self):
        Label(self.root, text="所有元素数n:").grid(row=0,sticky=E)
        Label(self.root, text="取出的元素数m:").grid(row=1,sticky=E)
        Label(self.root, text="不可重复组合数:").grid(row=2,sticky=E)
        Label(self.root, text="可重复组合数:").grid(row=3,sticky=E)
        self.e1 = Entry(self.root)
        self.m = StringVar()
        self.e2 = Entry(self.root,textvariable=self.m)
        self.a1 = StringVar()
        self.e3 = Entry(self.root,textvariable=self.a1)
        self.a2 = StringVar()
        self.e4 = Entry(self.root,textvariable=self.a2)
        self.e1.grid(row=0, column=1)
        self.e2.grid(row=1, column=1)
        self.e3.grid(row=2, column=1)
        self.e4.grid(row=3, column=1)
        self.btnSer = Button(self.root, command=self.click, width=3, height=1,text='运行')
        self.btnSer.grid(row=4,column=1,sticky=E)
        btnQuit = Button(self.root, text='关闭窗口', command=self.root.quit, width=8, height=1)
        btnQuit.grid(row=4,column=2)

    def click(self):
        n=int(self.e1.get())
        m =int(self.e2.get())
        #组合数
        a1=math.factorial(n)/math.factorial(m)/math.factorial(n-m)
        self.a1.set(int(a1))
        #不可重复组合数
        a2=math.factorial(n+m-1)/(math.factorial(m)*math.factorial(n-1))
        self.a2.set(int(a2))
        
    def loop(self):
        self.root.resizable(False, False)   #禁止修改窗口大小
        self.createWidgets()
        self.drawCenter()                       #窗口居中
        self.root.mainloop()

if __name__ == '__main__':
    w = Window(width=350, height=150)
    w.loop()

有5个数字,取两个数字进行组合的计算结果。

组合数计算器.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容