运筹系列90:生产线运输问题的julia求解

1. 仅建模搬运问题

我们不妨假设仓库有3种物料需要搬运到生产线,搬运时间都是3min。
三种物料假设都需要搬运3件,有2个叉车可以进行搬运,每个叉车每次智能搬运一件。
问题建模入下:

using JuMP,HiGHS,GLPK
MAXNUM = 10000
model = Model(HiGHS.Optimizer)
set_silent(model)
# 3种物料,2个agv,一共需要搬运9次,共10个阶段
M = 3
A = 2
moveTime = [1,2,3]
moveNum = [3,3,3]
T = sum(moveNum) 

# 状态变量:叉车的剩余工作时间worktime,以及阶段时间stageTime
@variable(model, 0 <= worktime[1:T+1,1:A]);for j in 1:A;fix(worktime[1,j], 0; force=true);end
@variable(model, 0 <= stageTime[1:T+1])

# 决策变量及约束:每次搬运1件;总共搬运3件;叉车有空(worktime==0)时才能pick新的物料
@variable(model, pick[1:T,1:M,1:A]>=0,Bin)
@constraint(model, [t in 1:T],sum(pick[t,:,:])==1)
@constraint(model,[i in 1:M],sum(pick[:,i,:])==moveNum[i])
@constraint(model,[t in 1:T,j in 1:A],worktime[t,j]/MAXNUM<=1-sum(pick[t,:,j]))

# 状态转移函数,以及边界条件
@constraint(model,[t in 1:T,j in 1:A],worktime[t,j]-stageTime[t]+sum([pick[t,i,j]*moveTime[i] for i in 1:M])==worktime[t+1,j])
@constraint(model,[j in 1:A],stageTime[T+1]>=worktime[T+1,j])

# 最小化总时间
@objective(model, Min, sum(stageTime))
optimize!(model)
print("最少需要时间:",Int(round(objective_value(model))))

# 下面时打印结果
function idx(pick,t,j)
    if t>T;return " ";end
    id = findfirst(x->x==1,value.(pick[t, :, j]))
    if id == nothing;return " ";else;return id;end
end

for t in 1:T
    println(t,": ",idx(pick,t,1)," ",idx(pick,t,2),", ",value.(worktime)[t,:],
    ", ",value.(worktime)[t,:]+[sum([value.(pick)[t,i,j]*moveTime[i] for i in 1:M]) for j in 1:A],", ",value.(stageTime)[t])
end
t=T+1
println(t,": ",idx(pick,t,1)," ",idx(pick,t,2),", ",value.(worktime)[t,:],", ",value.(worktime)[t,:],", ",value.(stageTime)[t])

2. 使用SDDP进行建模

需要增加一个delivered状态变量,用于跟踪已搬运的物料数量:
同时解除控制变量pick的整数约束,否则无法求解。

using SDDP,HiGHS
moveTime = [1,2,3]
moveNum = [3,3,3]
T = sum(moveNum)
A = 2
M = 3
MAXNUM = 1000

model = SDDP.LinearPolicyGraph(
    stages = T+1,
    lower_bound = 0.0,
    optimizer = HiGHS.Optimizer,
) do sp, t
    @variable(sp, 0 <= stagetime)
    @variable(sp, 0 <= worktime[1:A], SDDP.State, initial_value = 0)
    @variable(sp, 0 <= delivered[1:M]<=maximum(moveNum), SDDP.State, initial_value = 0)
    if t<=T
        @variable(sp, 1>=pick[1:M,1:A]>=0);@constraint(sp, sum(pick)==1)
        @constraint(sp, [j in 1:A],worktime[j].in/MAXNUM<=1-sum(pick[:,j]))
        @constraint(sp, [j in 1:A],worktime[j].in - stagetime +sum([pick[i,j]*moveTime[i] for i in 1:M]) == worktime[j].out)
        @constraint(sp, [i in 1:M],delivered[i].in+sum(pick[i,:])==delivered[i].out)
    else
        @variable(sp, pick[1:M,1:A]==0);
        for i in 1:M;fix(delivered[i].in, moveNum[i]; force = true);end
        @constraint(sp,[j in 1:A],stagetime>=worktime[j].in)
    end
    @stageobjective(sp, stagetime)
end
SDDP.train(model; iteration_limit = 100)
print(SDDP.calculate_bound(model))
simulations = SDDP.simulate(
    model,
    1,  #= number of replications =#
    [:pick];  #= variables to record =#
    skip_undefined_variables = true,
);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值