【MATLAB代码】基于模拟退化算法的船舶调度优化问题、船舶进港排班
目录一、模型建立二、模型数据三、模拟退火算法编写四、运行结果一、模型建立符号定义:g——港口位置 ggg ∈\in∈ G,1,2,…nG,{1,2,…n}G,1,2,…niii——泊位位置iii ∈\in∈ I,1,2,…nI, {1,2,…n}I,1,2,…njjj——船舶位置jjj ∈\in∈ J,1,2,…nJ,{1,2,…n}J,1,2,…nTwjTwjTwj——船j的等待时间TkjTkj
一、模型建立
符号定义:
g——港口位置 g g g ∈ \in ∈ G , 1 , 2 , … n G,{1,2,…n} G,1,2,…n
i i i——泊位位置 i i i ∈ \in ∈ I , 1 , 2 , … n I, {1,2,…n} I,1,2,…n
j j j——船舶位置 j j j ∈ \in ∈ J , 1 , 2 , … n J,{1,2,…n} J,1,2,…n
T w j Twj Twj——船j的等待时间
T k j Tkj Tkj——船j的卸货时间(一个集装箱的卸货时间是15分钟)
T a j Taj Taj——船j的到达时间
T l j Tlj Tlj——船j的离开时间( T l j = T a j + T k j + T w j Tlj=Taj +Tkj+ Twj Tlj=Taj+Tkj+Twj)
D j Dj Dj——船j吃水深度
L j Lj Lj——船j长度
W g i Wgi Wgi——港口g泊位i的水深
L g i Lgi Lgi——港口g中泊位i的长度
X g p i j X{{_{g}^{p}}_{ij}} Xgpij=1船j在港口g的泊位i中第p接受服务, =0船j在港口g的泊位i中不是第p接受服务
C s j {{C}_{sj}} Csj——船j的航行成本
C w j {{C}_{wj}} Cwj——船j的等待成本(8000元/小时)
C t j {{C}_{tj}} Ctj——船j到达港口后的集装箱运输成本
N j {{N}_{j}} Nj——船j的集装箱总量(z:重箱量; k:空箱量)
P P P——船舶单位航行成本(5元/(t*km))
A i {{A}_{i}} Ai——目的港口的坐标 A i ′ A_{i}^{'} Ai′——空箱到达目的港口的坐标
C S Z {{C}_{SZ}} CSZ——重箱运输成本(单位成本15元/km)
C s k {{C}_{sk}} Csk——空箱运输成本(单位成本10元/km)
d j {{d}_{j}} dj——船j重箱商品实际要达到的地理坐标
P——船舶靠港次序(Z——船舶靠港总次序)
船舶经济航速为40km/h
数学模型如下:
(1) min T = ∑ g ∈ G ∑ i ∈ I ∑ j ∈ J ∑ p ∈ Z ( T w j + T k j ) X g i j p \min T=\sum\limits_{g\in G}{\sum\limits_{i\in I}{\sum\limits_{j\in J}{\sum\limits_{p\in Z}{\left( {{T}_{wj}}+{{T}_{kj}} \right)}}}}X_{{{g}_{ij}}}^{p} minT=g∈G∑i∈I∑j∈J∑p∈Z∑(Twj+Tkj)Xgijp 使船舶在港时间最短
(2) min C = ∑ j ( C s j + C w j + C t j ) \min C=\sum\limits_{j}{\left( {{C}_{sj}}+{{C}_{wj}}+{{C}_{tj}} \right)} minC=j∑(Csj+Cwj+Ctj) 船公司的货运成本最小
(3) T w j = T l j − T a j − T k j ≥ 0 {{T}_{wj}}={{T}_{lj}}-{{T}_{aj}}-{{T}_{kj}}\ge 0 Twj=Tlj−Taj−Tkj≥0 船舶等待时间大于等于0
(4) X g i j p × X g i j p + 1 × ( T l j − T a j ) ≥ 0 X_{{{g}_{ij}}}^{p}\times X_{{{g}_{ij}}}^{p+1}\times ({{T}_{lj}}-{{T}_{aj}})\ge 0 Xgijp×Xgijp+1×(Tlj−Taj)≥0 必须要求前一艘离开另一艘才开始服务
(5) C s j = N j × p × A j {{C}_{sj}}={{N}_{j}}\times p\times {{A}_{j}} Csj=Nj×p×Aj 船 j的航行成本=集装箱总数单位航行距离成本距离
(6) C w j = C t × T w j {{C}_{wj}}={{C}_{t}}\times {{T}_{wj}} Cwj=Ct×Twj 船j的等待成本=单位等待成本*等待时间
(7) N = K + Z N=K+Z N=K+Z 集装箱总量=重箱数+空箱数
(8)停泊船的吃水深度小于泊位水深;船的长度小于泊位长度,即船都有靠泊的基本条件。
(1)(2)为目标函数,(3)——(8)为约束条件
其实这个问题非常简单,就是一个指派问题,给每一艘船指定一个港口,然后就可以计算得到每个船的等待时间、航行距离等等信息。知道了这个问题,程序就非常好解决啦。
二、模型数据
营口港与大连港的距离为210千米,为简化作出以下示意图
2个港口的情况(在这一部分中,为了计算方便将原数据按一定比例缩小)
| 港口 | 泊位数 | 集装箱货物吞吐量(万TEU) |
|---|---|---|
| 1 | 3 | 2万 |
| 2 | 3 | 3万 |
船舶数据
| 船舶 | 总箱数 | 重箱数 | 空箱数 | 到达时间 | 最快结束装卸时间(不等待,不移港) |
|---|---|---|---|---|---|
| 1 | 150 | 120 | 30 | 6:00 | 30h |
| 2 | 100 | 50 | 50 | 7:00 | 12.5h |
| 3 | 200 | 100 | 100 | 8:00 | 25h |
| 4 | 100 | 70 | 30 | 9:00 | 17.5h |
| 5 | 150 | 100 | 50 | 10:00 | 25h |
| 6 | 150 | 110 | 40 | 11:00 | 27.5h |
| 7 | 200 | 150 | 50 | 12:00 | 37.5h |
| 8 | 200 | 160 | 140 | 13:00 | 40h |
| 9 | 200 | 160 | 40 | 14:00 | 40h |
| 10 | 100 | 70 | 30 | 15:00 | 17.5h |
三、模拟退火算法编写
主文件:main.m
clc;
clear;
close all;
%% 算法参数
T0=5000; % 初始温度
Tend=1e-3; % 终止温度
L=500; % 各温度下的迭代次数(链长)
q=0.9; %降温速率
num_bowei = [3 3];%泊位数量
num_boat = 10; %船的数量
N = num_boat;
%% 初始解
S1 = ceil(sum(num_bowei)*rand(1,num_boat));
%% 输出随机解的路径和总距离
Rlength=PathLength(S1);
disp(['总距离:',num2str(Rlength)]);
%% 计算迭代的次数Time
% Time=ceil(double(solve(['1000*(0.9)^x=',num2str(Tend)])));
Time=132;
count=0; %迭代计数
Obj=zeros(Time,1); %目标值矩阵初始化
track=zeros(Time,N); %每代的最优路线矩阵初始化
%% 迭代
while T0>Tend
count=count+1; %更新迭代次数
temp=zeros(L,N+1);
for k=1:L
%% 产生新解
S2=NewAnswer(S1);
%% Metropolis法则判断是否接受新解
[S1,R]=Metropolis(S1,S2,T0); %Metropolis 抽样算法
temp(k,:)=[S1 R]; %记录下一路线的及其路程
end
%% 记录每次迭代过程的最优路线
[d0,index]=min(temp(:,end)); %找出当前温度下最优路线
if count==1 || d0<Obj(count-1)
Obj(count)=d0; %如果当前温度下最优路程小于上一路程则记录当前路程
else
Obj(count)=Obj(count-1);%如果当前温度下最优路程大于上一路程则记录上一路程
end
track(count,:)=temp(index,1:end-1); %记录当前温度的最优路线
T0=q*T0; %降温
% fprintf(1,'%d\n',count) %输出当前迭代次数
end
%% 优化过程迭代图
figure
plot(1:count,Obj)
xlabel('迭代次数')
ylabel('距离')
title('优化过程')
Result(track(end,:));
目标函数计算
function len=PathLength(Chrom)
%% 计算各个体的路径长度
% 输入:
load = [
150
100
200
100
150
150
200
200
200
100];
num_zhong = [120
50
100
70
100
110
150
160
160
70
];
num_kong = [30
50
100
30
50
40
50
140
40
30
];
arrive_time = 6:1:15;
num_bowei = [3 3];%泊位数量
num_boat = 10; %穿的数量
%仿真求解适应度值
[NIND,num_boat]=size(Chrom);
wait_time = zeros(1,num_boat);
departure_time = zeros(1,num_boat);
service_time = zeros(1,sum(num_bowei));
c_wait = zeros(1,num_boat); %等待费用
c_sail = zeros(1,num_boat); %航行成本
c_transfer = zeros(1,num_boat); %转移成本
x=Chrom;
for j=1:1:num_boat
if x(j) > num_bowei(1) % 选择第二个港口,到达时间要延迟
arrive_time(j) = arrive_time(j) + 210/40;
c_transfer(j) = (num_zhong(j) * 15 + num_kong(j) * 10) * 210;
c_sail(j) = load(j) * 5 * 210;
end
if arrive_time(j) > service_time(x(j)) % 没有被占用,直接服务
wait_time(j) = 0;
departure_time(j) = arrive_time(j) + load(j)*15/60;
service_time(x(j)) = departure_time(j);
else % 已经被占用了
wait_time(j) = service_time(x(j)) - arrive_time(j);
departure_time(j) = arrive_time(j) + wait_time(j) + load(j)*15/60;
service_time(x(j)) = departure_time(j);
end
end
c_wait = wait_time .* 8000;
%len = sum(wait_time);
len = sum(c_wait) + sum(c_sail) + sum(c_transfer);
四、运行结果
非常简洁。
最后,博主专注于论文的复现工作,有兴趣的同学可以私信共同探讨。相关代码已经上传到资源共享,点击我的空间查看分享代码。
更多推荐


所有评论(0)