SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

楼主: shiyiming
打印 上一主题 下一主题

sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
11#
 楼主| 发表于 2011-3-15 12:39:14 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

[code:36z2wh41]data ypxm1;
        array n[5]; array t[5];        array r[5];       
        retain T1-T5 N1-N5 r1-r5 0;
        do i=1 to 150 ;
                x1=rand('uniform'); x2=rand('uniform');x3=rand('uniform');x4=rand('exponential'); x5=rand('exponential'); x6=rand('exponential');
                y =0.5*x4;        
                if (i =1) then        y =0;
           do ii =1 to 5;
                        if t[ii] >r[ii] then do;       
                                n[ii] =max(0, n[ii]-1);
                                t[ii] =max(0, t[ii] -r[ii]);                               
                                r[ii] =2.5*x6;
                        end;
                end;
                tt =sum(tt, y); **time o'clock;       
                sfdd =1;
                n_min =min(of n[*]);
                n_sum =sum(of n[*]);
                do ii =1 to 5;
                        if n[ii] >0 then t[ii] =sum(t[ii], y);
                end;
                if (n_sum <30) then do ii =1 to 5;
                        if n[ii] =n_min then do;
                            xzfwck =ii;
                                n[ii] =sum(n[ii], 1);
                                if n[ii] = 1 then do;
                                        r[ii] =2.5*x5; t[ii] =sum(t[ii], y);
                                end;
                                leave;
                        end;
                end;
                else if (n_sum >=30)then do;
                        if x3 <0.5 then do;
                                xzfwck =ii;
                                do ii =1 to 5;                                       
                                        if n[ii] =n_min then do;                                               
                                                n[ii] =sum(n[ii], 1);
                                                leave;
                                        end;
                                end;                                       
                        end;
                        else sfdd =0;
                end;       
                output;
        end;
run; [/code:36z2wh41]
还有一些东西我没有想的很明白。其中的道理对于我来说,理解起来有些困难。京剧
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
12#
 楼主| 发表于 2011-3-16 15:35:49 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

首先,给大家说声抱歉啊,这两天由于比较忙,还没来得及关注这上边的这个帖子。我非常感谢叫京剧的这位朋友,他在编写那段程序时,肯定花了些心思进去的,
我运行了程序,也认真的看了几遍,我认为他设计思路方法都比较好,也比较接近完成出队列那块模拟,但是我注意到了一点,那就是在程序中的那个r[ii] 应该指的是顾客办理的业务实际所需要的时间(不包括等待时间),而最外层的那个do i=1 to 150的循环,代表的是150个顾客,有150条观测值,每一条观测,代表的是一位顾客的所有信息。在这个循环内每循环一次,就需要随机产生一个y值:代表的是前后两位顾客到达的时间间隔,也可理解为两条观测信息的时间差。假如说从0时刻开始,过了第一个产生的y值时间段后的那个时刻,第一个顾客到达,他办理的业务实际所需的时间为京剧那段程序中的随机产生的r[ii],这样依次循环下去,每个循环中随机产生一个y值,就可以推出下一个顾客的到达,而每一个顾客就好像是自身携带了一个不同的r[ii]一样,因为每位顾客实际办理完业务所花费的时间不同(这里也不包括排队等候的时间),而在京剧的那段程序中的do i=1 to 150循环内,产生的r[ii] 有两个值:r[ii] =2.5*x6 和 r[ii] =2.5*x5,这样对仿真的可信度会再次降低。程序中还有些比较小的事项,那就是sas不能严格区分大小写,有些变量定义重复了,不过对这个问题不太影响,总之非常感谢哪位叫京剧的朋友。
   
   
    为了避免前面那个较复杂多队列模型的影响和程序代码较长的问题,我把问题转换为最简单的单队列模型来解决,然后再去考虑多队列,因为只针对出队列,所以变量可以先考虑少些,窗口,等待类型等可以先不用考虑,只需解决出队列这块就行:
   
    设计sas程序,完成单队列的模型。需要用到的主变量有:相邻两客户到达的时间间隔y(服从指数分布的随机数,参数可设为0.3-0.6),客户实际办理完业务所需时间z(服从伽马分布的随机数,形状参数设为2.5),当前队列的排队人数(N)
   
    基本设计思路可以为,通过循环的操作产生一定量的观测(可取150),每条观测里边的变量值可以反应的是每个客户的信息(比如,到达时刻,当前排队人数等)——》然后循环内随机产生一个y值,和z值;N+1(N的初值为0),定义一个时间表变量(Time,初值也为0),Time=Time+y;——》output 打印,再循环,其中在每一次循环中还需加入判断,队列最前边的客户是否已办理完业务,是,则N-1;最好再定义一个变量,表示的是此时刻与上一时刻之间是否有客户已办完业务,是为1,否为0,这样能够更好反应出出队列的情况。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
13#
 楼主| 发表于 2011-3-17 16:11:57 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

程序模块可以为下面这段(供参照)
data a;
retain seed time N 0;
do i=1 to 150;
   x1=rand('exponential');
   y=0.4*x1;                    /*相邻两客户间的时间间隔*/
   time=sum(time,y);            /*时刻表*/
   z=rangam(seed,2.5);          /*客户实际办理完业务所需时间z*/
   N=sum(N,1);                  /*此时刻的排队人数*/
   /*
(代码省略部分)判断队列最前边的客户是否完成业务办理,即出队列(此时完成N-1)
再增加个变量,反应是否有出队列情况,有:1,无:0
   */
output;
end;
run;

终归问题归结为:就是用sas语言判断队列最前边的客户是否完成业务办理。

如果lag 函数的下标可以为变量,则问题比较容易解决了,我也用了比较多的数组办法不成,
其中貌似lag函数是可以解决的,它好像是队列函数。所以需要sas的朋友们帮我解决下这个麻烦哦!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
14#
 楼主| 发表于 2011-3-18 12:37:43 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

知道的就帮帮忙,不太清楚的也支点招吗,谢谢各位了!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
15#
 楼主| 发表于 2011-3-19 21:17:00 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

这么久都没人搭理我了,看来也只有自己搭自己了! 呜呜!呜呜! <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
不过我还是蛮希望得到论坛里朋友们的帮忙,希望你们能够帮我看看下边这段程序出错的缘由是什么呢?主要是数组那块,有什么好的办法
663  data a;
664  retain seed time N test 0;
665  retain k 1 r1-r30 0;
666  array r{30} r1-r30;
667  do i=1 to 150;
668  x1=rand('exponential');
669  y=0.4*x1;                            /*相邻两客户间的时间间隔*/
670  time=sum(time,y);                    /*时刻表*/
671  test=sum(test,y);                    /*比较测试变量*/
672  z=rangam(seed,2.5);                  /*客户实际办理完业务所需时间z*/
673  r(i)=z;                              /*用一个数组变量记录一个客户的实际办理完业务所需要花费的时间*/
674  N=sum(N,1);                          /*此时刻的排队人数*/
675  if(i&gt;1 and test&gt;=lag1(r(k))) then do;   /*出队列的情况时*/
676       N=sum(N,-1);
677       test=sum(test,-lag1(r(k)));
678       k+1;
679  end;
680  output;
681  end;
682  run;

ERROR: Array subscript out of range at line 673 column 1.
seed=0 time=6.5053489615 N=30 t=0 k=1 r1=5.0543248264 r2=4.1951733069 r3=1.705578679 r4=2.5924380015 r5=4.3783195493 r6=3.9666829069 r7=3.7741148642 r8=3.6177123486
r9=3.1815895984 r10=3.5323863883 r11=2.5843302065 r12=2.7075425969 r13=2.1221648417 r14=0.6802652604 r15=1.3761185163 r16=3.3514339174 r17=0.3632845083
r18=2.3099530204 r19=4.6675621206 r20=4.0174800602 r21=0.7062898593 r22=1.8473863286 r23=3.0907366931 r24=1.9369234141 r25=3.5461257712 r26=1.1660437241
r27=2.3036868635 r28=1.7507675047 r29=2.4960357055 r30=6.5663601574 i=31 x1=1.2270577758 y=0.4908231103 test=6.5053489615 z=5.3211699255 _ERROR_=1 _N_=1
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
16#
 楼主| 发表于 2011-3-20 11:50:37 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

有谁比较清楚上面那段程序,数组变量出现这种 ERROR: Array subscript out of range at line 673 column 1.
错误原因的就解释下吗?拜托各位牛哥了!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
17#
 楼主| 发表于 2011-3-20 13:13:09 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

array r{30} r1-r30;
667 do i=1 to 150;
673 r(i)=z;


i=31的时候你值放哪里啊 <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
18#
 楼主| 发表于 2011-3-20 15:34:25 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

[quote=&quot;superkuhasu&quot;:29x4kst3]array r{30} r1-r30;
667 do i=1 to 150;
673 r(i)=z;


i=31的时候你值放哪里啊 <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->[/quote:29x4kst3]

也对哈,i=31的时候值没地方放了,把30换成150,就不会出错了!原来考虑的是定义30个数组变量就足够了,而定义150个确实是太浪费资源了,
我的把它稍微改一下,这个数组问题解决了。非常感谢super哥,不过还有些程序逻辑问题可能要问大家!!@
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
19#
 楼主| 发表于 2011-3-20 17:19:29 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

[quote=&quot;superkuhasu&quot;:3t9trprv]array r{30} r1-r30;
667 do i=1 to 150;
673 r(i)=z;


i=31的时候你值放哪里啊 <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->[/quote:3t9trprv]

这下又来个小问题了,我把数组名r的长度从30改为150后,是没问题的。另外我想在r(i)=z;语句前面加一个限制条件应该是可以的,( if(i&lt;=30) then r(i)=z; )
但是还是出同样的错误,我已经避免了当 i&gt;=30时,值没地方放情况了啊,这点还没想明白,请高手些指教!!!

加入了限制条件(if(i&lt;=30))后的程序如下:
data a(drop= i);
retain seed time N test 0;
retain k 1 r1-r30 0;
array r{30} r1-r30;
do i=1 to 150;
x1=rand('exponential');
y=0.4*x1; /*相邻两客户间的时间间隔*/
time=sum(time,y); /*时刻表*/
test=sum(test,y); /*比较测试变量*/
z=rangam(seed,2.5); /*客户实际办理完业务所需时间z*/
N=sum(N,1); /*此时刻的排队人数*/
if(i&lt;=30) then r(i)=z; /*用一个数组变量记录一个客户的实际办理完业务所需要花费的时间*/
if(i&gt;1 and test&gt;=lag1(r(k))) then do; /*出队列的情况时*/
    N=sum(N,-1);
    test=sum(test,-lag1(r(k)));
    k=sum(k,1);
end;
output;
end;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
20#
 楼主| 发表于 2011-3-20 19:41:28 | 只看该作者

Re: sas的朋友们求助大家一个sas程序设计(关于银行队列的仿真模型中队列人数的减少问题)

你要看log的反馈。人家说几行几列有问题
r(k)你找谁去啊~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2025-6-12 21:30 , Processed in 0.096258 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表