python實現全排列程式碼(回溯、深度優先搜尋)
從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的一個排列。當m=n時所有的排列情況叫全排列。
公式:全排列數f(n)=n!(定義0!=1)
1 遞迴實現全排列(回溯思想)
1.1 思想
舉個例子,比如你要對a,b,c三個字元進行全排列,那麼它的全排列有abc,acb,bac,bca,cba,cab這六種可能就是當指標指向第一個元素a時,它可以是其本身a(即和自己進行交換),還可以和b,c進行交換,故有3種可能,當第一個元素a確定以後,指標移向第二位置,第二個位置可以和其本身b及其後的元素c進行交換,又可以形成兩種排列,當指標指向第三個元素c的時候,這個時候其後沒有元素了,此時,則確定了一組排列,輸出。但是每次輸出後要把陣列恢復為原來的樣子。
1.2 python實現
def permutations(arr,position,end): if position == end: print(arr) else: for index in range(position,end): arr[index],arr[position] = arr[position],arr[index] permutations(arr,position + 1,end) arr[index],arr[index] # 還原到交換前的狀態,為了進行下一次交換 arr = [1,2,3,4] permutations(arr,len(arr))
2 深度優先搜尋(DFS)實現全排列
2.1 思想
定義全排列問題:輸入一個長度為n的列表arr,輸出arr的全排列。
(1)首先可以確定的是,每一種全排列的結果中包含的列表長度均是n。想象面前有n個空盒子,現在要把這n個數放到這些空盒子裡去,每個盒子只能放一個數。那麼第一個盒子中可以放的選擇是n種,可以使用一個迴圈來逐個嘗試。
for index in range(0,len(arr)):
temp[position] = arr[index]
(2)第一個盒子放完後,就該往第二個盒子裡放了。假設第一個盒子裡放的是arr的第一個數,那麼第二個盒子就只能放第2~n個數了(不能重複)。為此引入visit列表用來標記arr中哪些數字被使用過了。初始化:
visit = [True,True,True]
這樣,當第一個位置已經使用過時,就在visit裡做標記:visit = [False,True]
因此放第一個盒子的程式碼可以改寫如下:
for index in range(0,len(arr)): if visit[index] == True: temp[position] = arr[index] visit[index] = False
(3)當第k個盒子處理完畢後,處理下一個盒子直接呼叫dfs(k+1)即可,也就是遞迴呼叫。解決了當下該如何做,下一步也就知道怎麼做了。
(4)遞迴呼叫的一定要注意的問題是遞迴呼叫的出口,否則迴圈呼叫下去程式會崩潰無法執行。在這個問題中什麼時候結束遞迴呼叫呢?答案是當這n個盒子都放滿了,即處理到第n+1個盒子時結束呼叫,同時輸出此時的排列結果。
2.2 python實現
visit = [True,True] temp = ["" for x in range(0,4)] def dfs(position): # 遞迴出口 if position == len(arr): print(temp) return # 遞迴主體 for index in range(0,len(arr)): if visit[index] == True: temp[position] = arr[index] visit[index] = False # 試探 dfs(position + 1) visit[index] = True # 回溯。非常重要 arr = [1,4] dfs(0)
註釋了“非常重要”的語句是不能省略的,省略後僅出現[1,4]一條結果。dfs(k+1)前後的兩條語句分別稱之為試探和回溯。
3 combination和permutations函式的區別
permutations方法重在排列:
import itertools n=3 a=[str(i) for i in range(n)] s="" s=s.join(a) for i in itertools.permutations(s,n): print (''.join(i)) # 結果 012 021 102 120 201 210
combinations方法重在組合:
import itertools n=3 a=[str(i) for i in range(n)] s="" s=s.join(a) for i in itertools.combinations(s,n): print (''.join(i)) # 結果 012
以上這篇python實現全排列程式碼(回溯、深度優先搜尋)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。