前のページ|次のページ

CALL LEXPERMルーチン

複数の変数の非欠損値の重複しないすべての順列を辞書式順序で生成します。

カテゴリ: 組み合わせ
操作: %SYSCALLマクロステートメントで呼び出されると、CALL LEXPERMの引数から引用符が削除されます。 詳細については、CALLルーチンと%SYSCALLマクロステートメントを使用するを参照してください。

構文

CALL LEXPERM(count, variable-1 <, …, variable-N>);

必須引数

count

1から順列数までの範囲の整数値が含まれる数値変数を指定します。

variable

すべての数値変数または同じ長さのすべての文字変数を指定します。これらの変数の値は、LEXPERMによって置換されます。

要件 LEXPERMルーチンを呼び出す前にこれらの変数を初期化します。

詳細

重複しない順列数の決定

これらの変数は、その後に示された式で使用するために定義されます。
N
置換される変数の数(引数の数から1を引いた数)を指定します。
M
置換される変数間の欠損値の数を指定します。
d
引数間の重複しない非欠損値の数を指定します。
Ni
i=1からi=dまでの場合、Niにはi番目の重複しない値のインスタンスを指定します。
引数の非欠損値の重複しない順列数は、次のように表されます。

CALL LEXPERM処理

引数countが1からPまでの各整数値を受け入れるループで、CALL LEXPERMルーチンを使用します。CALL LEXPERMで0より小さい値が返されたときにループを終了する場合、Pを計算する必要はありません。
1=count<Pの場合、次のアクションが実行されます。
  • 引数の種類と長さに不整合がないか確認が行われます。
  • M個の欠損値が最後のM個の引数に割り当てられます。
  • countの後の最初のN-M個の引数にN-M個の非欠損値が昇順で割り当てられます。
  • CALL LEXPERMは1を返します。
1<count<=Pの場合、次のアクションが実行されます。
  • 次の非欠損値の重複しない順列が辞書式順序で生成されます。
  • variable-1からvariable-Iは変更されずvariable-J (J=I+1)が変更された場合、CALL LEXPERMはJを返します。
count>Pの場合、CALL LEXPERMは–1を返します。
第1引数が順序どおりでないCALL LEXPERMルーチンが実行された場合、結果は役に立たない可能性があります。特に、変数を初期化した直後に第1引数がKのCALL LEXPERMを実行した場合、K番目の順列は取得されません(Kが1の場合を除く)。K番目の順列を取得するには、第1引数に1からKまでの値を正しい順序で渡すCALL LEXPERMをK回実行する必要があります。

マクロとCALL LEXPERMルーチンを使用する

%SYSCALLマクロを使用するときにLEXPERMルーチンを呼び出せます。この場合、variable引数は同じ長さにする必要はありませんが、同じ種類にする必要があります。%SYSCALLで引数が数値であることが識別されると、%SYSCALLは戻り値の形式を調整します。
CALL LEXPERMルーチンの実行中にエラーが発生すると、次の両方の値が設定されます。
  • &SYSERRには4よりも大きい値が割り当てられます。
  • &SYSINFOには-100よりも小さい値が割り当てられます。
エラーがない場合、&SYSERRはゼロに設定されて、&SYSINFOは次のいずれかの値に設定されます。
  • 1(1=count<Pの場合)
  • 1(1<count<=Pでvariable-1の値が変更された場合)
  • J(1<count<=Pでvariable-1からvariable-Iは変更されず、variable-J(J=I+1)が変更された場合)
  • -1(count>Pの場合)

比較

SASには、すべての順列を生成する3つの関数またはCALLルーチンがあります。
  • ALLPERM: 複数の変数の値(欠損値または非欠損値)の考えられるすべての順列を生成します。各順列は、前の順列に基づいて形成されます(2つの連続する値を交換)。
  • LEXPERM:複数の変数の非欠損値の重複しないすべての順列を生成します。順列は、辞書式順序で生成されます。
  • LEXPERK: N個の変数の非欠損値からK個の重複しないすべての順列を生成します。順列は、辞書式順序で生成されます。
ALLPERMは最も速い関数およびCALLルーチンです。最も遅いのはLEXPERKです。

例1: DATAステップでCALL LEXPERMを使用する

次の例では、複数の変数の非欠損値の重複しないすべての順列を辞書式順序で生成するDATAステップを使用します。
data _null_;
   array x[4] $3 ('ant' 'bee' 'cat' 'dog');
   n=dim(x);
   nfact=fact(n);
   do i=1 to nfact;
      call lexperm(i, of x[*]);
      put i 5. +2 x[*];
   end;
run;
次の出力がログに書き込まれます。
    1 ant bee cat dog 2 ant bee dog cat 3 ant cat bee dog 4 ant cat dog bee 5 ant dog bee cat 6 ant dog cat bee 7 bee ant cat dog 8 bee ant dog cat 9 bee cat ant dog 10 bee cat dog ant 11 bee dog ant cat 12 bee dog cat ant 13 cat ant bee dog 14 cat ant dog bee 15 cat bee ant dog 16 cat bee dog ant 17 cat dog ant bee 18 cat dog bee ant 19 dog ant bee cat 20 dog ant cat bee 21 dog bee ant cat 22 dog bee cat ant 23 dog cat ant bee 24 dog cat bee ant

例2: マクロとCALL LEXPERMを使用する

マクロで使用されるCALL LEXPERMルーチンの例を次に示します。出力には%SYSINFOマクロ用の値が含まれます。
%macro test;
   %let x1=ant;
   %let x2=baboon;
   %let x3=baboon;
   %let x4=hippopotamus;
   %let n=4;
   %let nperm=%sysfunc(perm(4));
   %do j=1 %to &nperm;
      %syscall lexperm(j, x1, x2, x3, x4);
      %let jfmt=%qsysfunc(putn(&j, 5.));
      %put &jfmt: &x1 &x2 &x3 &x4 sysinfo=&sysinfo;
      %if &sysinfo<0 %then %let j=%eval(&nperm+1);
   %end;
 %mend;
     
 %test;
     
次の出力がログに書き込まれます。
    1: ant baboon baboon hippopotamus sysinfo=1 2: ant baboon hippopotamus baboon sysinfo=3 3: ant hippopotamus baboon baboon sysinfo=2 4: baboon ant baboon hippopotamus sysinfo=1 5: baboon ant hippopotamus baboon sysinfo=3 6: baboon baboon ant hippopotamus sysinfo=2 7: baboon baboon hippopotamus ant sysinfo=3 8: baboon hippopotamus ant baboon sysinfo=2 9: baboon hippopotamus baboon ant sysinfo=3 10: hippopotamus ant baboon baboon sysinfo=1 11: hippopotamus baboon ant baboon sysinfo=2 12: hippopotamus baboon baboon ant sysinfo=3 13: hippopotamus baboon baboon ant sysinfo=-1

関連項目:

前のページ|次のページ|ページの先頭へ