JSL ヘルプ: ベクトルまたはリストのすべての順列を作成する方法ベクトルまたはリストのすべての順列を列挙するための JSL を作成する最良の方法を見つけようとしています。
私が見つけた有望そうなアルゴリズムの 1 つは、ヒープのアルゴリズムhttps://en.wikipedia.org/wiki/Heap%27s_algorithm 、しかし、これをコード化する方法がわからないようです。誰かここで助けてくれませんか?
ベクトルまたはリストのサイズが大きくなると、出力のサイズが階乗的に大きくなることがわかりました (k 個の項目の順列の数は k です!)。 )、したがって、順列のリスト内の各項目を生成し、その順列に対して操作を実行し、次の順列を生成する必要がなくなったときにそれを破棄する方法にも興味があります。
Re: JSL ヘルプ: ベクトルまたはリストのすべての順列を作成する方法これは、Craige のスクリプトに基づいて作成した関数です。
</CODE></PRE><PRE><CODE class="">Names Default To Here( 1 );
Clear Log();
permutate = Function( {list},
per = New Namespace();
per:swap = Function( {targetList, firstPosition, secondPosition}, //returns a list with elements in firstPosition and secondPosition swapped
{temp},
temp = targetList[firstPosition];
targetList[firstPosition] = targetList[secondPosition];
targetList[secondPosition] = temp;
Return( targetList );
);
per:generate = Function( {k},
{i, temp},
If( k == 1,
Insert Into( per:result, Eval List( List( per:A ) ) ), //else
per:generate( k - 1 );
// Generate permutations for kth swapped with each k-1 initial
For( i = 0, i < k - 1, i += 1,
// Swap choice dependent on parity of k (even or odd)
If( Mod( k, 2 ) == 0,
per:A = per:swap( per:A, k, i + 1 ), //else
per:A = per:swap( per:A, 1, k )
);
per:generate( k - 1 );
);
)
);
per:result = {};
per:A = list;
per:generate( N Items( per:A ) );
result = per:result;
Delete Namespaces( per );
Return( result );
);
A = {"a", "b", "c", "d"};
permutate( A );
Re: JSL ヘルプ: ベクトルまたはリストのすべての順列を作成する方法お二人ともコードをありがとうございます。役に立ちました。再帰はいつも頭が痛くなるのですが、JSL では順列のシーケンスの出力をリストや行列に割り当てるような方法で再帰を行うのは簡単ではないようです。
ジェネレーター関数を使用した後、私がやりたかったことには計算時間がかかりすぎることがわかりました。
ここに問題があります:緩和フラクション (MF)。説明されていますここ。これは、2 つのグループを比較するための Wilcoxson Rank-Sum 検定統計量 (W) に基づいています。したがって、私がやりたかったのは、与えられたサンプルサイズを持つ 2 つのグループの W のすべての可能な値を (可能なランクのすべての順列を使用して) リストし、そこからすべての可能な MF の値を取得することでした。私が本当に示したかったのは、MF が有効性を証明するために使用している基準が、両方のグループの分布が同じであるという帰無仮説の下で W の分布の臨界値と同等であるということでした。
私が問題を解決した方法は、各グループの基礎となる分布を仮定し、シミュレーション研究を行って、その仮定の下で MF の分布を取得することでした。(また、サンプルサイズが大きい場合、W は H0: (母集団に差がない) の下で漸近的に正規になるため、これも問題の一部を解決する別の方法です)。ただし、シミュレーションを使用すると、別の対立仮説の下で検出力を検証することもでき、分析がより完全になりました。
Re: JSL ヘルプ: ベクトルまたはリストのすべての順列を作成する方法質問の後半、その方法ないリスト全体を保存しますか?
素晴らしい質問です。 JMP が提供する唯一の答えは、JIM のソリューションが print() を実行する場所、または私のソリューションが write() を実行する場所からコードを呼び出すことであると私は信じています。 JMP がジェネレーターまたはコルーチンを提供している場合@XanGreggを使用すると、コードが必要なポイント (複数のポイント) から次のシーケンスをジェネレーターに要求できる、より柔軟なソリューションが得られます。 必要な場合は、事前にそれらを表にリストすることが最良の選択かもしれません。
プロジェクトについてさらに詳しく教えていただけますか? 14個全部見るのにかかる時間!または15!順列はおそらく禁止されています。 すべての順列を調べる前に十分な答えが見つかると期待している場合は、おそらくアニーリング アルゴリズムを使用して、ランダムな順列を使用する方が良い選択かもしれません。
Re: JSL ヘルプ: ベクトルまたはリストのすべての順列を作成する方法// Heap's algorithm from https://en.wikipedia.org/wiki/Heap%27s_algorithm
// note: the above uses 0-based arrays, JMP uses 1-based. The above also
// must be using call-by-reference and JMP uses call-by-value. below uses
// a global array A rather than trying to find a way to pass the array by
// reference. For similar reasons, swap(x,y) is expanded in-line.
generate = Function( {k},
{i, temp},
If( k == 1,
Write( "\!n", A );//
, //else
// Generate permutations with kth unaltered
// Initially k == length(A)
generate( k - 1 );
// Generate permutations for kth swapped with each k-1 initial
For( i = 0, i < k - 1, i += 1,
// Swap choice dependent on parity of k (even or odd)
If( Mod( k, 2 ) == 0,
temp = A[i + 1];
A[i + 1] = A[k];
A[k] = temp;
, //else
temp = A[1];
A[1] = A[k];
A[k] = temp;
);
generate( k - 1 );
);
)
);
A = [1 2];
generate( N Cols( A ) );
A = {"a", "b", "c"};
generate( N Items( A ) );
A = 1 :: 4;
generate( N Cols( A ) );
[1 2]
[2 1]
{"a"、"b"、"c"}
{"b"、"a"、"c"}
{"タクシー"}
{"a"、"c"、"b"}
{"b"、"c"、"a"}
{"c"、"b"、"a"}
[1 2 3 4]
[2 1 3 4]
[3 1 2 4]
[1 3 2 4]
[2 3 1 4]
[3 2 1 4]
[4 2 1 3]
[2 4 1 3]
[1 4 2 3]
[4 1 2 3]
[2 1 4 3]
[1 2 4 3]
[1 3 4 2]
[3 1 4 2]
[4 1 3 2]
[1 4 3 2]
[3 4 1 2]
[4 3 1 2]
[4 3 2 1]
[3 4 2 1]
[2 4 3 1]
[4 2 3 1]
[3 2 4 1]
[2 3 4 1]
ウィキペディア版を再参照させてくれてありがとう! 前回は、変換しやすい別のバリエーションを見つけました。
Re: JSL ヘルプ: ベクトルまたはリストのすべての順列を作成する方法コードの非再帰形式を JMP に変換しました。これが役立つかどうかを確認してください
generate = Function( {n, A},
//c is an encoding of the stack state. c[k] encodes the for-loop counter for when generate(k+1, A) is called
c = {};
For( i = 1, i <= n, i++, c[i] = 1 );
Print( A );
//i acts similarly to the stack pointer
i = 1;
While( i <= n,
If( c[i] < i,
If( Mod( i, 2 ) == 0,
//swap(A[0], A[i])
temp = A[1];
A[1] = A[i];
A[i] = temp;
,
//swap(A[c[i]], A[i])
temp = A[c[i]];
a[c[i]] = a[i];
a[i] = temp;
);
Print( A );
//Swap has occurred ending the for-loop. Simulate the increment of the for-loop counter
c[i] = c[i] + 1;
//Simulate recursive call reaching the base case by bringing the pointer to the base case analog in the array
i = 1;
,
//else
//Calling generate(i+1, A) has ended as the for-loop terminated. Reset the state and simulate popping the stack by incrementing the pointer.
c[i] = 1;
i = i + 1;
)
);
);