面试顺序问题的Matlab和Lingo解法

本文探讨了如何使用Lingo和Matlab解决面试顺序问题,以最小化全体面试者完成面试所需时间。通过数学建模设立优化目标和约束条件,最终得出面试顺序为4-1-2-3,最早能在9:24结束所有面试。

本文lingo解法来源[1]。

1 面试顺序问题

有 4 名同学到一家公司参加三个阶段的面试:公司要求每个同学都必须首先 找公司秘书初试,然后到部门主管处复试,最后到经理处参加面试,并且不允许插队(即 在任何一个阶段 4 名同学的顺序是一样的)。由于 4 名同学的专业背景不同,所以每人 在三个阶段的面试时间也不同,如下表所示。这 4 名同学约定他们全部面试完以后一起离开公司。假定现在时间是早晨 8:00,请问他们最早何时能离开公司?

秘书初试主管复试经理面试
同学甲131520
同学乙102018
同学丙201610
同学丁81015

2 建立模型

实际上,这个问题就是要安排 4 名同学的面试顺序,使完成全部面试所花费的时间最少。
t i j {{t}_{ij}} tij为第i名同学参加第 j 阶段面试需要的时间(已知),令 x i j {{x}_{ij}} xij表示第i名同学参加第j阶段面试的开始时间(不妨记早上 8:00 面试开始为 0 时刻) (i=1,2,3,4 ; j =1,2,3),T 为完成全部面试所花费的最少时间。
优化目标:
min ⁡ { T } = { [ max ⁡ i   ( x i 3 + t i 3 ) ] } \min \left\{ T \right\}=\left\{ \left[ \underset{i}{\mathop{\max }}\,\left( {{x}_{i3}}+{{t}_{i3}} \right) \right] \right\} min{T}={[imax(xi3+ti3)]} (1)

约束条件:
1) 时间先后次序约束(每人只有参加完前一个阶段的面试后才能进入下一个阶段):
x i j + t i j ≤ x i , j + 1 , i = 1 , 2 , 3 , 4 , j = 1 , 2 {{x}_{ij}}+{{t}_{ij}}\le {{x}_{i,j+1}},i=1,2,3,4,j=1,2 xij+tijxi,j+1,i=1,2,3,4,j=1,2
2) 每个阶段j同一时间只能面试1名同学:用0−1变量 y i k {{y}_{ik}} yik表示第k名同学是否排在第i名同学前面(1 表示“是”,0 表示“否”)。
Alt
参考文献[1]中此处比较简略,本文按笔者理解较为详细阐述。
例如,当i=1,k=2时,y12=1表示第2个同学在第1个同学前面,y12=0表示第1个同学在第2个同学前面,假定此时是第一次面试j=1。
按照y12=1和y12=0分别画出时间线图:
y12=1

图1 y~12~=1

y12=0

图2 y~12~=0

上述两种情况分别需要满足:
在这里插入图片描述

上式可以写为:

在这里插入图片描述
所以第二个约束条件为

在这里插入图片描述
上式是一个非线性约束条件,可以将T写为一个较大常数M,转化为线性约束。
3) 非线性的优化目标改写成如下线性优化目标
在这里插入图片描述
4) 所有变量的非负约束和 y i k {{y}_{ik}} yik的0-1约束。

3 模型求解

3.1 Lingo求解

程序:

model:
Title 面试问题; 
SETS: Person/1..4/; 
Stage/1..3/; 
PXS(Person,Stage): T, X; 
PXP(Person,Person)|&1 #LT# &2: Y; 
ENDSETS 
DATA: 
T=13, 15, 20, 10 , 20 , 18, 20, 16, 10, 8, 10, 15; 
ENDDATA 
[obj] min=MAXT; 
MAXT>= @max(PXS(i,j)|j#EQ#@size(stage):x(i,j)+t(i,j)); 
! 只有参加完前一个阶段的面试后才能进入下一个阶段; 
@for(PXS(i,j)|j#LT#@size(stage):[ORDER]x(i,j)+t(i,j)<x(i,j+1)); 
! 同一时间只能面试1名同学; 
@for(Stage(j):   
    @for(PXP(i,k):[SORT1]x(i,j)+t(i,j)-x(k,j)<MAXT*Y(i,k));  
    @for(PXP(i,k):[SORT2]x(k,j)+t(k,j)-x(i,j)<MAXT*(1-Y(i,k)))); 
@for(PXP: @bin(y)); 
end

结果:所有面试完成至少需要 84min,面试顺序为 4-1-2-3(丁-甲- 乙-丙)。早上 8:00 面试开始,最早 9:24 面试可以全部结束。

3.2 Matlab求解

程序:

% 面试顺序问题matlab程序
clear;clc;close all;
%% 输入数据
t = [13, 15, 20;
    10, 20, 18;
    20, 16, 10;
    8, 10, 15];
A = zeros(20,19);
b  = zeros(19,1);
M = sum(sum(t)); % M设置为所有同学总计约束时间
cnt = 1;
%% 约束条件
% 约束1
for loop1 = 1:8
    for loop2 = 1:2
        A(loop1, (ceil(loop1/2)-1)*3+mod(loop1,2)*-1+2) = 1;
        A(loop1, (ceil(loop1/2)-1)*3+mod(loop1,2)*-1+3) = -1;
        b(loop1) = -1*t(ceil(loop1/2), mod(loop1,2)*-1+2);
    end
end
% 约束2
for loopk = 3:4
    for loopi = 1:loopk-1
        for loopj = 1:3
            if loopk == 3
                temp = 1;
            else
                temp =3;
            end
            A(8+cnt,(loopi-1)*3+loopj) = 1;
            A(8+cnt,(loopk-1)*3+loopj) = -1;
            A(8+cnt,12+temp+loopi) = -1*M;
            b(8+cnt) = -1*t(loopi,loopj);
            A(9+cnt,(loopk-1)*3+loopj) = 1;
            A(9+cnt,(loopi-1)*3+loopj) = -1;
            A(9+cnt,12+temp+loopi) = M;
            b(9+cnt) = -1*t(loopk, loopj)+M;
            cnt = cnt+2;
        end
    end
end
sizeA = size(A,1);
cnt = 1;
for loopj = 1:3
     % k=2,i=1
    A(sizeA+cnt,loopj) =1; A(sizeA+cnt,3+loopj) =-1;   A(sizeA+cnt,13) =-1*M;     
    b(sizeA+cnt)  = -1*t(1,loopj); 
    A(sizeA+cnt+1,loopj) = -1; A(sizeA+cnt+1,3+loopj) =1; A(sizeA+cnt+1,13) = M;     
    b(sizeA+cnt+1)  = M-1*t(2,loopj);
    cnt = cnt+2;
end
% 约束3
sizeA = size(A,1);
for loopi = 1:4
    A(sizeA+loopi,(loopi-1)*3+3) = 1;
    A(sizeA+loopi,19) = -1;
    b(sizeA+loopi) = -1*t(loopi,3);
end
% 边界约束
lb = zeros(19,1);
ub = inf(19,1); ub(13:18) = 1;
intcon = 1:19;
%% 目标函数
f = zeros(19,1); f(19) = 1;
%% 优化
options = optimoptions('intlinprog','Display','off');
[x,fval,exitflag,output] = intlinprog(f,intcon,A,b,[],[],lb,ub,[],options);
if exitflag==1 && fval==M
    disp('find');
    x_opt = x;
    fval_opt = fval;
end
x
fval

计算结果为:
8 21 36 21 36 56 31 58 74 0 8 18 0 0 0 1 1 1 84
对应19个决策变量,分别为
x 1 ∼ x 12 : {{x}_{1}}\sim{{x}_{12}}: x1x12:每名学生面试开始时间;
x 13 ∼ x 18 : {{x}_{13}}\sim{{x}_{18}}: x13x18:第k名同学是否在第i名前面,分别为第2名同学是否在第1名同学前面,3是否在1、2前面,4是否在1、2、3前面;
x 19 : {{x}_{19}}: x19:全部面试所花费的最少时间。
所以,所有面试完成至少需要 84min,面试顺序为 4-1-2-3(丁-甲- 乙-丙)。早上 8:00 面试开始,最早 9:24 面试可以全部结束。

4 总结

1、0-1变量 y i k {{y}_{ik}} yik的引入。
2、非线性约束的线性化,T写为一个较大常数M。
3、目标函数中包含max时的处理。

参考文献:
[1]: 司守奎. 数学建模算法与程序[M]. 国防工业出版社,2013.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值