前のページ|次のページ

CALL LEXPERKルーチン

n個の変数から一度にk個を取り出した非欠損値の重複しないすべての順列を辞書式順序で生成します。

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

構文

CALL LEXPERK(count, k, variable-1, …, variable-n);

必須引数

count

ループで1から順列数までの値を割り当てる整数変数を指定します。

k

各順列の項目数を指定する、1からn(1とnを含む)までの間の整数定数、変数または式を指定します。

variable

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

要件 LEXPERKルーチンを呼び出す前にこれらの変数を初期化します。
ヒント LEXPERKを呼び出すと、最初のk個の変数に1つの順列の値が含まれます。

詳細

基本

CALL LEXPERKルーチンはループで使用します。CALL LEXPERKの第1引数は1から変数の非欠損値の重複しないk個の順列数までの各整数を受け付けます。このループ内のLEXPERKの各呼び出しで、kの値は同じである必要があります。

順列数

すべての変数に等しくない非欠損値が含まれる場合、順列数はPERM(,k)個です。欠損値を含む変数の数がm個ですべての非欠損値が等しくない場合、欠損値は順列から除外されるため、CALL LEXPERKではPERM(n-m,k)個の順列を生成します。一部の変数に等しい値が含まれる場合、正確な順列数を計算することは困難です。正確な順列数を計算できない場合は、CALL LEXPERKルーチンのかわりにLEXPERK関数を使用します。

CALL LEXPERK処理

LEXPERKルーチンを初めて呼び出すと、次のアクションが実行されます。
  • 引数の種類と長さに不整合がないか確認が行われます。
  • m個の欠損値が最後のm個の引数に割り当てられます。
  • n-mの非欠損値がcountに続く最初のn-m引数に昇順で割り当てられます。
後続の呼び出しでは、最後の順列まで(最後の順列を含む)、k個の非欠損値の次の重複しない順列が辞書式順序で生成されます。
LEXPERKルーチンを呼び出す場合に第1引数が順序が違っていると、その結果は役に立ちません。特に、変数を初期化した直後に第1引数がjのLEXPERKルーチンを呼び出した場合、j番目の順列は取得されません(jが1の場合を除く)。j番目の順列を取得するには、第1引数に1からjまでの値をそのままの順序で取得して、LEXPERKをj回呼び出す必要があります。

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

%SYSCALLマクロを使用するときにLEXPERKルーチンを呼び出せます。この場合、変数の引数を同一の長さにする必要はありませんが、同じ種類にする必要があります。%SYSCALLで引数が数値であることが識別されると、%SYSCALLは戻り値の形式を調整します。
CALL LEXPERKルーチンの実行中にエラーが発生すると、次の両方の値が設定されます。
  • &SYSERRには4よりも大きい値が割り当てられます。
  • &SYSINFOには-100よりも小さい値が割り当てられます。
エラーがない場合、&SYSERRはゼロに設定されて、&SYSINFOは次のいずれかの値に設定されます。
  • 1(count=1で少なくとも1つの変数に非欠損値が含まれる場合)
  • 1(count>1でvariable-1の値が変更された場合)
  • j(count>1でvariable-1からvariable-iは変更されず、variable-j(j=i+1)が変更された場合)
  • –1(重複しないすべての順列がすでに生成済みの場合)

比較

CALL LEXPERKルーチンは、n個の変数から一度にk個を取り出した非欠損値の重複しないすべての順列を辞書式順序で生成します。CALL ALLPERMルーチンは、複数の変数の値のすべての順列を変化量の小さい順に生成します。

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

CALL LEXPERKルーチンの例を次に示します。
data _null_;
   array x[5] $3 ('V' 'W' 'X' 'Y' 'Z');
   n=dim(x);
   k=3;
   nperm=perm(n, k);
   do j=1 to nperm;
      call lexperk(j, k, of x[*]);
      put j 5. +3 x1-x3;
   end;
run;
次の出力がログに書き込まれます。
    1   V W X 2   V W Y 3   V W Z 4   V X W 5   V X Y 6   V X Z 7   V Y W 8   V Y X 9   V Y Z 10   V Z W 11   V Z X 12   V Z Y 13   W V X 14   W V Y 15   W V Z 16   W X V 17   W X Y 18   W X Z 19   W Y V 20   W Y X 21   W Y Z 22   W Z V 23   W Z X 24   W Z Y 25   X V W 26   X V Y 27   X V Z 28   X W V 29   X W Y 30   X W Z 31   X Y V 32   X Y W 33   X Y Z 34   X Z V 35   X Z W 36   X Z Y 37   Y V W 38   Y V X 39   Y V Z 40   Y W V 41   Y W X 42   Y W Z 43   Y X V 44   Y X W 45   Y X Z 46   Y Z V 47   Y Z W 48   Y Z X 49   Z V W 50   Z V X 51   Z V Y 52   Z W V 53   Z W X 54   Z W Y 55   Z X V 56   Z X W 57   Z X Y 58   Z Y V 59   Z Y W 60   Z Y X

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

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

関連項目:

関数:
前のページ|次のページ|ページの先頭へ