SAS中文论坛

标题: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ?  [打印本页]

作者: shiyiming    时间: 2009-9-13 12:28
标题: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
During World War II German submarines (U-boats) patrolled the Atlantic ocean looking for enemy ships to sink. Suppose a U-boat has 16 torpedoes (underwater missiles) to start off with when they left their U-boat pens in occupied France.
Suppose that each U-boat attack on an enemy ship uses 1 torpedo with probability 0.7, 2 torpedoes with probability 0.2, and 3 torpedoes with probability 0.1. (This is because big targets may require more hits and some torpedoes miss their target etc.)
We wish to estimate Y = the total number of enemy ships that will be attacked until the U-boat has run out of torpedoes. This includes the last ship even if there aren‟t enough torpedoes to sink it.
(a) Write a SAS program to simulate the distribution of Y. Perform 1000 simulations. If you wish to write a SAS macro then you may assume that the code below has been given to you and your code to be inserted at the position of the /*******/. Alternatively, you could attempt to do the simulation entirely within a data step.

%MACRO uboat(numiters);
%DO iter=1 %TO &numiters;
/**********/
/* Append results to dataset simout */ DATA simout; %IF &iter=1 %THEN %DO; SET sim; %END; %ELSE %DO; SET simout sim; %END; RUN; %END; /* End of %DO loop */
PROC MEANS DATA=simout; VAR Y; TITLE "Summary statistics of the ships attacked; &numiters iterations"; RUN;
PROC FREQ DATA=simout;
TABLES Y; RUN;
%MEND(uboat);
%uboat(1000);


[color=#FF0080:1pdevxd7]%macro uboat(numiters);
    %do iter=1 %to &numiters;
      data sim;
        num=0;
        Y=0;
        keep Y;
        %do %WHILE (num LE 16);
        ship=ranuni(0);
        if  0 LE ship LE 0.7 then num=num+1 ;
        else if  ship GE 0.9 then num=num+3 ;
        else  num=num+2;
        Y=Y+1;
        %end;
        run;
    data simout;
   
       %if &iter=1 %then %do;
       set sim;
       %end;
       %else %do;
       set simout sim;
       %end;
        run;
%end;

proc means data=simout;
    var Y;
     run;
proc freq data=simout;
    tables Y;
     run;
%mend uboat;
%uboat(1000);[/color:1pdevxd7]
[/color]
作者: shiyiming    时间: 2009-9-13 14:50
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
应该使用do while语句而不是%do %while语句,代码可以改写一下,可参考jingju11的帖子
[code:2c079e3k]%macro uboat(numiters);
        %do iter=1 %to &numiters;
                data sim;
                        num=0;
                        Y=0;
                        keep Y;
                        do WHILE (num LE 16);
                                ship=ranuni(0);
                                if 0 LE ship LE 0.7 then num=num+1 ;
                                else if ship GE 0.9 then num=num+3 ;
                                else num=num+2;
                                Y=Y+1;
                        end;
                run;
                data simout;
                        %if &iter=1 %then %do;
                                        set sim;
                                %end;
                        %else %do;
                                        set simout sim;
                                %end;
                run;
        %end;
        proc means data=simout;
                var Y;
        run;
        proc freq data=simout;
                tables Y;
        run;
%mend uboat;

%uboat(1000)[/code:2c079e3k]
作者: shiyiming    时间: 2009-9-13 15:53
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
答案还是错的 

                                        The FREQ Procedure

                                                    Cumulative    Cumulative
                      Y    Frequency     Percent     Frequency      Percent
                     ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
                      7           1        0.10             1         0.10
                      8          11        1.10            12         1.20
                      9          37        3.70            49         4.90
                     10          84        8.40           133        13.30
                     11         168       16.80           301        30.10
                     12         243       24.30           544        54.40
                     13         236       23.60           780        78.00
                     14         130       13.00           910        91.00
                     15          67        6.70           977        97.70
                     16          21        2.10           998        99.80
                     17           2        0.20          1000       100.00

这个应该到16就停了阿 怎么还有17呢!!!!
作者: shiyiming    时间: 2009-9-13 16:48
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
if语句的条件写的有问题呗
[code:10wpr2on]if 0 LE ship LE 0.7 then num=num+1 ;
else if ship LE 0.8 then num=num+2 ;
else num=num+3;[/code:10wpr2on]
作者: shiyiming    时间: 2009-9-13 17:29
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
555555  还是错的 y还是有17  
作者: shiyiming    时间: 2009-9-13 18:31
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
奥,是DO WHILE循环的条件不对
[code:2i7lezp5]do while(num lt 16);
or
do until(num ge 16);[/code:2i7lezp5]
作者: shiyiming    时间: 2009-9-14 09:17
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
missiles 数量可以(假设性的)大于16。想一想如下情形:uboat只剩下一个missile(用了15)。但是此时它仍然可以攻击需要两个missiles的船只:“This includes the last ship even if there aren‟t enough torpedoes to sink it.”所以只要已用的missiles小于16,最后的攻击必须做出,而不管你遇到了什么样的敌船(这样问题简单些)。

另外你的结果不必要和给定的相同。除非他用的是固定seed random number generator。如果他是,你用同样的seed,结果应该是相同的。
作者: shiyiming    时间: 2009-9-14 20:50
标题: Re: 能帮我看看我写的code到底哪里错了 为什么y不累计呢 ? 
[quote:2q9qwhbk]do while(num lt 16);
or
do until(num ge 16);[/quote:2q9qwhbk]

这个条件语句, 从hopewell来的,是正确的。

[code:2q9qwhbk]
data sampling;
        do sample=1 to 1000;
                Y=0;
                missiles=0;
                do until(missiles >= 16);*number of missiles may be presumably more than 16,that should be Okay;
                          ran=ranuni(1);  
                          missiles+ifn(ran<=0.7,1,ifn(ran<=0.9,2,3));*at last attack, u-boat may need more missiles than number of missiles left,but that still counts;
                          Y+1; *ships attacked and damaged;
/*  output;*/
                end;
                output;
        end;
run;[/code:2q9qwhbk]

咱们再老调重弹一边。此处可以用固定的seed,比如在这里的1。但是上一个的boat race 一定得用变化的seed。另外,missiles 可以有三个值 16 17 18.Y一定不大于16.




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2