全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
2687 5
2009-05-16

求助: 筛选问题

      有9个数,它们是1,2,3,4,5,6,7,8,9

      按照不重复组合排列,组成6个数,有84组排列组合。既:

1 2 3 4 5 6      1 2 3 4 5 7      1 2 3 4 5 8       1 2 3 4 5 9

1 2 3 4 6 7      1 2 3 4 6 8      1 2 3 4 6 9       1 2 3 4 7 8  。。。。。。

求助:怎样只排列组合几组(当然越少越好),这几组排列组合中,最少有一组包含上面9个数字的任意5个的组合

请问用什么方法?

谢谢!!

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2009-5-17 00:35:00

A macro can be found at  http://support.sas.com/techsup/technote/ts498.html
Here is the copy.

%macro combo(r)/parmbuff;
      %let i=2;
      %let things=;
      %do %while (%Qscan(&syspbuff,&i,%STR(,%))) ne );
        %let p&i="%Qscan(&syspbuff,&i,%STR(,%)))";
        %if &i=2 %then %let things=&&p&i;
        %else %let things=&things,&&p&i;
        %let i=%eval(&i+1);
      %end;
      %let n=%eval(&i-2);
       data combo;
            keep v1-v&r;
            array word $8  w1-w&n (&things);
            array rr (*) r1-r&r;
            array v $8  v1-v&r;
           %do i=1 %to &r;                    /* create the DO LOOPs */
             %if &i=1 %then %do;
               do r&i=1 to &n-(&r-&i);
               %end;
             %else %do;
               do r&i=r%eval(&i-1)+1 to &n-(&r-&i);
               %end;
             %end;
               do k=1 to &r;              /* select subscripted items */
               v(k)=word (rr(k));               /* for a SAS data set */
               put v(k)      '  ' @;                       /* for log */
               end;
               put;                                  /* writes to log */
               output;                    /* writes to a SAS data set */
           %do i=1 %to &r;
             end;                     /* create ENDs for the DO LOOPs */
             %end;
            put;
            run;
         proc print uniform data=combo;
            title "combinations of &n items taken &r at a time ";
            run;
%mend combo;
%combo(6,1,2,3,4,5,6,7,8,9)


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-17 11:59:00

谢谢 yongyitian 您的回复!!

   您这程序是将9个数, 按照不重复组合排列,组成6个数一组,得出所有的84组排列组合。

我上面的问题是不是没说清楚,我解释一下:

   我是想将9个数, 按照不重复组合排列,组成6个数一组,

再将所有的84组排列组合进行缩减,缩减到几组(越少越好),

但这几组的排列组合,要包含所有9个数中任意5个的组合。

求助:如何筛选缩减??

如果是得出所有的排列组合,用下列程序好象简单一些:

data a (keep=d1-d6);

array hm[9] (1 2 3 4 5 6 7 8 9 );

do i1=1 to 9; d1=hm{i1};

do i2=i1+1 to 9; d2=hm{i2};

do i3=i2+1 to 9; d3=hm{i3};

do i4=i3+1 to 9; d4=hm{i4};

do i5=i4+1 to 9; d5=hm{i5};

do i6=i5+1 to 9; d6=hm{i6};

output; end; end; end; end; end; end; run;

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-17 12:35:00

不知道楼主想要的可能会不会发生。因为9选6有84种可能,而9选5有126种可能,从84种中选126种可能是不是做不到。

还是我没读懂题?

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-17 17:51:00

我认为应该可以把。就看怎样筛选排列组合了。

例:假如筛选出的几组中,其中一组是:1 2 3 4 5 6

那么这一组就包含

1 2 3 4 5  , 1 2 3 4 6 , 1 2 3 5 6 , 1 2 4 5 6 , 1 3 4 5 6 , 2 3 4 5 6

9个数组合5中的6组。

[此贴子已经被作者于2009-5-19 22:00:56编辑过]

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-19 01:09:00

All right, here is a solution. The code is kind of long, so please simplify it by all means.

The basic ideas is to generate 2 sets containing all the combinations of 5 (a5 126 Obs) and 6 (a6 84 Obs) numbers, then for each of the observation in a5, compare it to each observation in a6 to see if the first is part of the latter.

Here are the codes:

/*Create set containing all combinations of 6 numbers, it contains 84 observations*/

data a6 (keep=d1-d6 Nbr);

array hm[9] (1 2 3 4 5 6 7 8 9 );

Nbr=0;

do i1=1 to 9; d1=hm{i1};

do i2=i1+1 to 9; d2=hm{i2};

do i3=i2+1 to 9; d3=hm{i3};

do i4=i3+1 to 9; d4=hm{i4};

do i5=i4+1 to 9; d5=hm{i5};

do i6=i5+1 to 9; d6=hm{i6};

nbr+1;

output; end; end; end; end; end; end; run;

/*Create set containing all combinations of 5 numbers, it contains 126 observations*/

data a5 (keep=d1-d5);

array hm[9] (1 2 3 4 5 6 7 8 9 );

do i1=1 to 9; d1=hm{i1};

do i2=i1+1 to 9; d2=hm{i2};

do i3=i2+1 to 9; d3=hm{i3};

do i4=i3+1 to 9; d4=hm{i4};

do i5=i4+1 to 9; d5=hm{i5};

output;  end; end; end; end; end; run;

/*Transpose a6, so each number is in a single column, so that it is easies to be put in a macro later */

proc transpose data=a6 out=a6t(drop=_name_);

run;

/*Create a table for future use, it contains the five digits and in what order number it would be in the 6 number

combinations*/

proc sql;

create table results

(d1 num, d2 num,d3 num, d4 num,d5 num,d5 num, Nbr num);

quit;

%macro AllResults;

%do i=1 %to 84;

/*For each of the 6 digit number, we want to change it in a set form, say 123456 in the form of

(1,2,3,4,5,6), we achieve that by using macro, that's why we did transpose earlier

*/

      proc sql noprint;

      select col&i into:compare separated by ','

      from a6t

      ;

      quit;

      %put &compare;

/*Pick each of the number in a5 and compare it with &compare, e.g. for 12345

we want to see if 1 we have all this 1 in (1,2,3,4,5,6), 2 in (1,2,3,4,5,6), 3 in (1,2,3,4,5,6),

      4 in (1,2,3,4,5,6) and 5 in (1,2,3,4,5,6), if it does we mark in which number it is and output the result

      */

      data temp(keep=d1-d5  nbr);

      set a5;

      if d1 in (&compare) and d2 in (&compare) and d3 in (&compare) and d4 in (&compare) and d5 in (&compare) then

                  do;

                        nbr=&i;

                        output;

                  end;

      run;

/*Export the reult to set results, so we can move on to the next number in a6*/

      proc sql;

      insert into results

      select *

      from temp;

      quit;

%end;

/*delete the temp set*/

proc sql;

drop table temp;

quit;

%mend;

%AllResults

/*Now we have all the senarios, e.g., for each 6 digit number what combination of 5 digit numbers it contains

but we want the story from another view, i.e. for each of the 5 digit number in what 6 digit number it is in, so we

sort by the 5 digits

*/

proc sort data=results;

by d1-d5;

run;

/*Now we know more, for example, we know 12345 is contained in the first four numbers of a6: 1 2 3 4, in this case

we only want to keep the first one*/

data results126;

set results;

 by d1-d5;

 if first.d5;

run;

/*Now we see that we caught all the 126 different cases, at the same time we know that some of the 6 digit numbers are used

more than once*/

proc sort data=results126 ;

      by nbr;

run;

/*Following code ensures that we use each 6 digit number once*/

data final(keep=nbr);

set results126;

      by nbr;

      if first.nbr;

run;

/*In case we want to know what they are...*/

data Used;

merge a6 final(in=in);

by nbr;

if in;

run;

[此贴子已经被作者于2009-5-19 1:27:44编辑过]

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群