📄 dock_sever_simulation.m
字号:
% Code of the Simulation and Model homework
% Author: Yu Guoqiang
% DAta: 2007-12-01
% 301
clear all
clc
%初始化子程序
sim_days=60; % 仿真天数(单位:天)
h=0.01; % 时间步长(单位:小时)
steps=sim_days*24/h; % 仿真总的步长
beta=10; % 指数分布参数
ships=sim_days*24/beta+50; % 仿真天数内可能入港油轮总数
data=1; % 存储日期变量
u=15000; % 油轮卸货速度(单位:桶/小时)
v=13000; % 向炼油厂供油速度(单位:桶/小时)
waittime=zeros(1, ships); % 存储各油轮等待时间
sum_time=0; % 总的仿真时间(单位:小时)
event=zeros(1, ships); % 存储事件油轮到达,event=1表示油轮入港,event=0表示没有油轮入港或者油轮卸货完毕
dock_status=0; % 码头忙闲状态,dock_status=0表示码头处于闲状态,dock_status=1表示码头处于忙状态
total_capacity=zeros(1, ships); % 入港油轮的总载油量
cap_tanker=zeros(1, ships); % 卸载时油轮的储油量(变量)
cap_oilcan=0; % 油罐的储油量
unloadtemp=0; % unloadtemp为表示卸货暂停的状态量
freetime=0; % freetime表示码头空闲数,freetime=0表示工作,freetime=1表示空闲
night=0; % night变量为是否为0:00——6:00的标志
sum_input=0; % 码头总进油量
sum_output=0; % 向炼油厂的总供油量
ql=0; % ql变量为为队列长度
sum_oilcan=0; % 仿真步长内油罐的储油量
unload_time = zeros(1, ships); % 存储各油轮卸货所用时间(单位:小时)
%油轮入港间隔服从均值为10的指数分布,利用均值分布产生上述指数分布,结合油轮载油量密度函数求得各油轮的载油量。
x=rand(1, ships); % 产生均匀分布的随机数
y=-10*log(x); % 产生服从指数分布的随机数
for i=1:ships
if x(i)<1/6 % 根据产生的随机数计算入港油轮的总载油量
total_capacity(i)=50000;
elseif x(i)<1/2
total_capacity(i)=60000;
elseif x(i)<5/6
total_capacity(i)=80000;
else
total_capacity(i)=100000;
end
end
sum_time_tanker=zeros(1, ships); % 存储第i艘油轮入港时距仿真开始的总时间
sum_time_tanker(1)=y(1);
for j=2:ships
sum_time_tanker(j)=sum_time_tanker(j-1)+y(j);
end
%时钟转移到第一艘油轮入港前
sum_time=fix(sum_time_tanker(1)/h)*h;
num_ship=1;
%逐步仿真系统各相关状态
for step=fix(sum_time_tanker(1)/h):steps
ql=0;
sum_time=sum_time+h;
nowtime=sum_time-(data-1)*24; % 仿真所处当天时刻(单位:小时)
if nowtime>=24
data=data+1;
end
delta=sum_time-sum_time_tanker(num_ship);
if((0<delta)&(delta<=0.01)) % 判断是否有油轮入港,记录在event数组中,并置位dock_status
event(num_ship)=1;
unload_time(num_ship)=0.95*total_capacity(num_ship)/u;
dock_status=1;
cap_tanker(num_ship)=total_capacity(num_ship);
num_ship=num_ship+1;
end
if nowtime>=6 % 判断油轮到达时间是否为凌晨0点到6点之间
if(dock_status==1) % 判断码头是否有船
if cap_oilcan<300000 % 判断油罐是否油满(设码头的储油量为30,0000桶)
if unloadtemp==0 % 是否卸货暂停
for j=1:ships
if event(j)==1
break
end
end
cap_tanker(j)=cap_tanker(j)-u*h; %卸货
cap_oilcan=cap_oilcan+u*h;
sum_input=sum_input+1;
end
else unloadtemp=1; %码头油满,置位卸货暂停标志
end
else freetime=freetime+1;
end
else night=1; %如果是夜里,置夜间标志位night
end
%以下为统计一步长的状态,并改变相应的状态量
for t=1:ships
if event(t)==1
waittime(t)=waittime(t)+0.01;
end
ql=ql+event(t);
end
if cap_tanker(j)<=0.05*total_capacity(j) %油轮剩余油量小于其总容量的5%,则卸货完毕
event(j)=0;
end
if cap_oilcan<(0.8*300000) %如果储油罐的储油量小于其容量的80%,则恢复卸货
unloadtemp=0;
end
if ql==0
dock_status=0;
end
%以下为给炼油厂供油的仿真
if cap_oilcan<5000
outputoil=0;
end
if cap_oilcan>50000
outputoil=1;
end
if(outputoil==1)
cap_oilcan=cap_oilcan-130;
sum_output=sum_output+1;
end
sum_oilcan=sum_oilcan+cap_oilcan;
end
%所有油轮的总等待时间
total_waittime=0; %所有144条船的总等待时间
wait_time_of_eachship=waittime-unload_time; %计算显示每条船的等待时间,在港时间减去自身卸货时间
for i=1:ships
total_waittime=total_waittime+wait_time_of_eachship(i);
end
%仿真结果输出
sprintf('取仿真天数为%d天,步长为%0.5g小时,仿真结果如下所示:\n\n%d天内受服务油轮数为:%d艘;\n码头油罐的平均储油量为:%d桶;\n码头的日平均进油量为:%d桶;\n码头向炼油厂的日平均供油量为:%d桶;\n码头的利用率为:%0.5g%%;\n油轮的平均等待时间为:%0.5g小时'...
,sim_days,h,sim_days,num_ship, sum_oilcan/(sim_days*24/h),...
sum_input*u*h/sim_days,...
sum_output*v*h/sim_days,...
(1-(freetime*0.01)/(24*sim_days))*100,...
total_waittime/num_ship)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -