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

加法原理和乘法原理,是排列組合中的二條基本原理,在解決計數問題中經常運用。掌握這兩條原理,并能正確區分他們,至關重要。

加法原理

若完成一件事情有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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容