私はABCDEF
を持っているとしましょう。その後、6があります!その文字列を並び替える順列。さて、私は、隣接する文字がない順列についてのみ扱いたいと思います。ことは、私これらの制約を満たすすべての順列を見てみたい:隣接文字のない文字列のすべての順列を生成するアルゴリズム
- BはAの隣にないか、またはC
- CはBの隣ではないか、D
- DはCの隣ではありません
:またはE//generate all 6! permutations //check all permutations and see where B is next to A || C //remove all instances //check all permutations and see where C is next to D //remove all instances //check all permutations and see where D is next to E //remove all instances //check all permutations and see where E is next to F //remove all instances
- Eは、このアルゴリズムへの私のアプローチは、以下の擬似コードであるDまたはF
の隣ではありません3210
しかし、これらのマスキング操作は非常に非効率的になり、特に私の文字列の長さが6より大きい場合、私は非常に長くなりすぎます。これをより効率的に行うにはどうすればいいですか?私はこれらの類似の投稿、1,2を見て、私を助けるかもしれないいくつかの重要なアイデアを抽出したいと考えていました。しかし、これはブルートフォースチェックでもあります。私は実際に最初からユニークなパターンだけを生成し、すべてを生成して1つずつチェックする必要はありません。
EDIT:現在のところ、これは私がすべての順列を生成するために使用しているものです。
static String[] designs;
static int index;
protected static String[] generateDesigns(int lengthOfSequence, int numOfPermutations){
designs = new String[numOfPermutations];
StringBuilder str = new StringBuilder("1");
for(int i = 2; i <= lengthOfSequence; i++)
str.append(i);
genDesigns("", str.toString()); //genDesigns(6) = 123456 will be the unique characters
return designs;
}
//generate all permutations for lenOfSequence characters
protected static void genDesigns(String prefix, String data){
int n = data.length();
if (n == 0) designs[index++] = prefix;
else {
for (int i = 0; i < n; i++)
genDesigns(prefix + data.charAt(i), data.substring(0, i) + data.substring(i+1, n));
}
}
まあ、見積もりをしましょう。 n個の文字にランダムパーマが与えられた場合、2つの特定の文字が互いに隣り合う確率は2(n-1)/(n(n-1))= 2/nである。これらの制約のn-1があるので、手のひら独立性の仮定では、ランダムなpermは、大きなnに対して(1-2/n)^(n-1)≈1/e^2≒0.135の確率で有効である。これが妥当な見積もりであれば、大きな利益を望むことはできません。有効パーマ(7または8の1つ)が多すぎます! –
Hmm、ここでは、そのような順列がいくつあるかを導出するために使用される実際の方程式があります: "隣接するものがランダム再配置の後で隣人のままである確率"、Amer。数学。月刊87(1980)、122-124 –
同じ公式。正式な派生があることを知ってもらいました(しかし、私はまったく驚いていません)。 –