全排列生成演算法(二)

2021-09-30 09:19:50 字數 1796 閱讀 6166

steinhaus-johnson-trotter演算法是一種基於最小變換的全排列生成演算法,對於排列a[1...n],該演算法通過將a[i],與a[i-1](或a[i+1])進行交換,生成下乙個排列,直到所有排列生成完畢為止,這樣,當前排列與其後繼排列只是兩個相鄰位置的元素發生了調換。

當然,為了防止重複生成某乙個排列,演算法並非隨意調換某兩個元素之間的位置,其生成全排列的具體規則如下。

這裡有幾個概念需要說明一下,所謂合法位置,是指該元素按照其移動方向移動,不會移動到排列陣列之外,例如對於<4,<1,<2,<3,此時對於元素4,如果繼續向左移動,就會超過陣列範圍,所以4的下乙個移動位置是非法位置。而且,所有元素,都只能向比自己小的元素的方向移動,如上面例子中的元素2,3,而元素1是不能夠移動到元素4的位置的。每次移動,都要對可以移動的所有元素中的最大者進行操作,上例中元素1,4不能移動,2,3都存在合法的移動方案,此時需要移動3,而不能移動2。合法移動之後,需要將所有大於移動元素的元素的移動方向反轉,上例中的元素3移動後的結果是4>,1,4>,對於其中的元素2,4,其對應的下乙個移動位置都是非法位置,而對於元素1,3,其下乙個移動位置的元素,都比他們要大,對於該排列就找不到乙個可以的移動方案,這說明該演算法已經達到終態,全排列生成結束。下面是該演算法的**

inline int sjtnext(unsigned int* index, size_t array_size, int* move)

if(index[i] > index[j])

}} //未發現合法的移動策略

if(j == array_size)

t = index[j];//要交換位置的元素

i = j + move[j];//發生交換的位置

swap(index, i, j);

swap(move, i, j);

//將所有比t大的元素的移動方向反轉

for(i = 0; i < array_size; ++i) }

return 0;}/*

* 基於最小變換的steinhaus–johnson–trotter演算法

*/void fullarray(char* array, size_t array_size)

arrayprint(array, array_size, index);

while(!sjtnext(index, array_size, move))

}

**使用了乙個伴隨陣列move標記對應位置元素的移動方向,在元素移動時,move陣列中的對應元素也要相應移動。該演算法從初始排列<1,<2,<3,<4開始,可以生成4元素的所有排列,直至最終排列<2,<1,3>,4>為止,其狀態轉移如下圖所示,該來自於wiki百科。

實際上該演算法是shimon even對於steinhaus-johnson-trotter三人提出的全排列生成演算法的改進演算法,在演算法中實際上還有乙個問題需要解決,就是對於給定的排列,如何判斷其所有元素的移動方向,如果上面所謂終態的移動方向是<2,<1,3>,<4,那麼這個狀態就還存在可行的移動方案。johnson(1963)給出了判斷當前排列各元素移動方向的方法,對於排列中的每個元素,判斷所有比該元素小的元素所生成序列的逆序數,如果逆序數為偶,則該元素的移動方向為向左,否則移動方向向右,我們用這條原則來看一下上面的終態2,1,3,4。對於元素1,沒有比1小的元素,此時我們認為,空序列的逆序數為偶,所以元素1的移動方向向左;對於元素2,比2小的元素形成的序列為1,單元素序列的逆序數為偶,所以2的移動方向向左;對於元素3,小於3的元素組成的序列為21,逆序數為1,奇數,所以3的移動方向向右;對於元素4,對應序列為213,逆序數為奇數,所以4的移動方向向右。根據該規則就可以知道,給定某一排列,其對應元素的移動方向是確定的。

全排列生成演算法

recursive generating 這個演算法接受乙個元素均不同的陣列,通過遞迴的呼叫以生成所有全排列序列。遞迴的原則在於,生成序列的全排列p a1,a2,an 等價於生成序列 這構成了遞迴演算法設計的deduction case 而base case,則是要生成全排列的序列只有乙個元素。整個...

全排列生成演算法

問題 生成1 n的全排列 生成乙個陣列中所有元素的全排列 思想 依據字典序順序,由前乙個排列,生成後乙個排列。字典序方法 輸入前乙個排列,輸出後乙個排列 vector nextpermutation vector p 主呼叫方法 void generatepermutation int n for ...

全排列生成演算法

我們假如有一串式子,排列組合的結果會有很多種,全排列就是按照字典序有序的將所有的排列組合的性質的陳列出來 問題可以這麼描述 對於給定的集合a,其中的n個元素互不相同,如何輸出這n個元素的所有排列 全排列 我們來這麼看這個問題,加入有n個資料要進行全排列,我們可以假想我們面前有n個盒子 每一次我們有大...