演算法——全排列

冷咖啡热牛奶發表於2024-07-02

一、使用遞迴演算法求全排列(暴力法)
求 {1 2 3 4 5......n}的全排列的思路如下:

(1)讓第一個數不同,得到n個數列(辦法是:把第1個和後面每個數交換即可):

1 2 3 4 5......n

2 1 3 4 5......n

.....

n 2 3 4 5......1

以上n個數列,只要第一個數不同,不管後面n-1個數是怎麼排列的,這n個數列都不同。

這是遞迴的第一層

(2)繼續:在上面的每個數列中,去掉第一個數,對後面的n-1個數進行類似的排列。例如從上面第2行的{2 1 3 4 5......n}進入第二層(去掉首位2):

1 3 4 5......n

3 1 4 5......n

......

n 3 4 5......1

以上n-1個數列,只要第一個數不同,不管後面n-2個數是怎麼排列的,這n-1個數列都不同。

這是遞迴的第二層。

(3)繼續以上過程,直到用完所有數字。

而我們不難得出,這個演算法總共有n×(n-1)×(n-2)×......×1個情況。

程式碼顯示

 1 def swap(s,i,j):     # 實現陣列裡i,j 互換位置
 2     temp = s[i]
 3     s[i] = s[j]
 4     s[j] = temp
 5 #全排列實現
 6 def perm(begin,end):
 7     global num
 8     if begin == end:
 9         print(nums)
10     else:
11         for i in range(begin,end+1):
12             swap(nums,begin,i)
13             perm(begin+1,end)
14             swap(nums,begin,i)
15 num = 0
16 nums = [1,2,3,4,5,6,7,8,9,10]
17 perm(0,9)

如果想要計算次數,則只需將每一個排列結束時的print語句改成num+=1即可

求n個數中隨機m個數的全排列

例如在10個數中取任意3個數的全排列,在遞迴程式中只修改一個地方就可以了:

1 if begin == 3:         #將end改為3即可
2     print(nums[:3])

相關文章