对于生产问题的平衡优化

  1. 问题描述

假设某产品的生产线由5道工序,3个工作站,3个工人组成。工序之间的优先关系如图1所示。

图1 工序优先关系图

不同员工加工各个工序的时间各不相同,分别如表1,2,3所示。求解最佳的工序分配方案与人员指派方案,使得目标函数取得最小值。

表1 员工1在各工作站加工各工序所用时间

1

2

3

1

14.87

21.29

18.89

2

19.78

11.58

13.36

3

22.89

15.35

22.70

4

19.35

15.31

10.49

5

21.93

16.29

12.76

表2 员工2在各工作站加工各工序所用时间

1

2

3

1

13.82

20.77

20.75

2

18.98

11.18

11.63

3

20.64

15.29

21.91

4

17.29

14.62

10.66

5

21.84

16.03

10.87

表3 员工3在各工作站加工各工序所用时间

1

2

3

1

15.79

22.90

19.60

2

18.48

12.45

11.35

3

22.16

17.51

22.58

4

19.16

14.61

12.25

5

20.34

17.80

10.17

  1. 符号说明

  1. 数学建模

思路1:用变量A代表工人与工位之间的指派关系,用变量X代表工序与工位之间的分配关系。问题可描述为:

其中c为系数矩阵,A、X都是决策变量所组成的矩阵,并且其取值都是0或1。

不知道其属于哪种规划问题,首先考虑采用benders分解方法求解,但是benders分解所适用的形式是类似于这种形式的问题。

其次用固定一个变量,求解另一个变量,再固定另一个,反过来求解这一个变量并不断循环的思路进行优化。(但是结果可能有问题)。

思路2:用一个变量,既能表示工序与工位的分配关系,又能表示工人与工位的指派关系。问题的模型可以简化为一个线性规划问题。

约束为:

  1. 优化求解

思路一:

# 通过固定一个变量,求解另一个变量的思想进行优化。轮流对A和X进行优化
import gurobipy as gp
from gurobipy import GRB
import numpy as np
import math
import pandas as pd
import matplotlib.pyplot as plt

Index_works=10
Stations=10
Works=10
a=np.ones((Index_works,Stations))
e=np.random.rand(Index_works,Stations)#随机生成的系数
# e=np.array([[0.36732504, 0.59868139, 0.52340548, 0.89953054],
#  [0.58727324, 0.44467678, 0.50980262, 0.56266788],
#  [0.3325161,  0.12459947, 0.99864395, 0.9913541 ],
#  [0.80171981, 0.37986221, 0.89358609, 0.66410582],])
# 固定a求解x的一阶段问题
def FSP(a):
    m1 = gp.Model("first-stage")
    X_is = m1.addMVar((Index_works,Stations),vtype=GRB.BINARY,name='X')
    obj = a@X_is@e
    m1.setObjective(obj.sum(), GRB.MINIMIZE)
    for index_work in range(Index_works):
        m1.addConstr(X_is[index_work,:].sum()==1,name="row"+str(index_work))
    for station in range(Stations):
        m1.addConstr(X_is[:,station].sum()==1,name="col"+str(station))
    m1.addConstr(X_is[1,1]==0,name="col"+str(station))
    m1.addConstr(X_is[0,0]==1,name="col"+str(station))
    m1.update()
    m1.setParam('OutputFlag',0)
    m1.Params.InfUnbdInfo = 1 
    m1.optimize()
    if m1.Status == 5: # model is unbounded
        print('wujie')
    if m1.Status == 2: # model is optimal
        obj = m1.objVal
        x_list = [X_is.X[i,j] for i in range(Index_works) for j in range(Stations)]
        x_array = np.array(x_list, dtype = int)
        return m1.Status,obj,x_array.reshape(Index_works,Stations)
# 固定x,求解a的二阶段问题
def SSP(x):
    m2 = gp.Model("second-stage")
    A_sw = m2.addMVar((Stations,Works),vtype=GRB.BINARY,name='A')
    obj2 = A_sw@x@e
    m2.setObjective(obj2.sum(), GRB.MINIMIZE)
    for work in range(Works):
        m2.addConstr(A_sw[work,:].sum()==1,name="row"+str(work))
    for station in range(Stations):
        m2.addConstr(A_sw[:,station].sum()==1,name="col"+str(station))
    m2.addConstr(A_sw[1,1]==1,name="col"+str(station))
    m2.addConstr(A_sw[0,0]==1,name="col"+str(station))
    m2.update()
    m2.setParam('OutputFlag',0)
    m2.Params.InfUnbdInfo = 1 
    m2.optimize()
    if m2.Status == 5: # model is unbounded
        print('wujie')
    if m2.Status == 2: # model is optimal
        obj = m2.objVal
        A_list = [A_sw.X[i,j] for i in range(Stations) for j in range(Works)]
        A_array = np.array(A_list, dtype = int)
        return m2.Status,obj,A_array.reshape(Stations,Works)
data=[]
for i in range(10):
    a1=FSP(a)[2]
    b1=FSP(a)[1]
    a2=SSP(a1)[2]
    b2=SSP(a1)[1]
    a=a2
    # print(b1,b2)
    data.append(b1)
plt.plot(data)
plt.show()

思路二求解结果:

import gurobipy as gp
from gurobipy import GRB
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import networkx as nx

G=nx.DiGraph() #创建什么都没有的空图
Index_works=5
Stations=3
Workers=3
A=np.array([[0,1,1,0,0],[0,0,0,1,0],[0,0,0,0,1],[0,0,0,0,1],[0,0,0,0,0]])#优先关系
relation = np.argwhere(A==1)+1
num_relation = np.size(relation,0)#优先关系有几组
# start=[relation[i][0] for i in range(num_relation)]#边的起点列表
# to=[relation[i][1] for i in range(num_relation)]#边的终点列表
# for j in range(len(start)):
#     G.add_edge(start[j], to[j]) 
# # pos = [(i+1,i) for i in range(num_relation)]
# nx.draw(G,with_labels=True)
# plt.show()
T=np.array([[[14.87,21.29,18.89],
[19.78,11.58,13.36],
[22.89,15.35,22.70],
[19.35,15.31,10.49],
[21.93,16.29,12.76]],
[[13.82,20.77,20.75],
[18.98,11.18,11.63],
[20.64,15.29,21.91],
[17.29,14.62,10.66],
[21.84,16.03,10.87]],
[[15.79,22.90,19.60],
[18.48,12.45,11.35],
[22.16,17.51,22.58],
[19.16,14.61,12.25],
[20.34,17.80,10.17]]])#时间矩阵 

m = gp.Model()
X_isw = m.addMVar((Workers,Index_works,Stations),vtype=GRB.BINARY,name='X')
res = np.multiply(T, X_isw)
obj1 = res.sum().sum()
m.setObjective(obj1,GRB.MINIMIZE)
#约束1:保证每个工作只有一个工作站来做
for index_work in range(Index_works):
    m.addConstr(X_isw[:,index_work,:].sum()>=1,name='cons1_%d'%(index_work))
# 一个工人指派给一个工作站==>每个表只有一列大于0==>每张表的和大于1同时小于等于Index_works-Workers+1
for worker in range(Workers):
    m.addConstr(X_isw[worker,:,:].sum()<=Index_works-Workers+1,name='cons2_%d'%(worker))
    m.addConstr(X_isw[worker,:,:].sum()>=1,name='cons3_%d'%(worker))      
#每个工作站都要有工作
for station in range(Stations):
    m.addConstr(X_isw[:,:,station].sum()>=1,name='cons4_%d'%(station))
# 约束2:保障工序间的优先关系
# for worker in range(Workers):
#     for i in range(num_relation):
#         for station in range(Stations):
#             a=(station+1)*X_isw[worker,relation[i][0]-1,station]
#             b=(station+1)*X_isw[worker,relation[i][1]-1,station]
#             m.addConstr(a<=b,name='cons5_%d_%d_%d'%(worker,i,station))      
# 约束3:保障每个工作站都不超过生产节拍
for station in range(Stations):
    m.addConstr(res[:,:,station].sum()<=300,name='cons2_%d'%(station))
m.update()
m.setParam('OutputFlag',0)
m.Params.InfUnbdInfo = 1 
m.optimize()
m.write('model1.lp')
if m.Status == 5: # model is unbounded
    print('无界解')
if m.Status == 2: # model is optimal
    print('求得该问题最优解为:')
    obj = m.objVal
    print(obj)
    x_list = [X_isw.X[i,j,k] for i in range(Stations) for j in range(Index_works)for k in range(Workers)]
    x_array = np.array(x_list, dtype = int)
    result = x_array.reshape(Workers,Index_works,Stations)
    ans = []
    index = ['工序'+str(i+1) for i in range(Index_works)]
    columns = ['工位'+str(i+1) for i in range(Stations)]
    for worker in range(Workers):
        ans.append(pd.DataFrame(result[worker],index=index,columns=columns))
        print('工人'+str(worker+1)+'分配情况:')
        print(ans[worker])
elif m.Status == 3:
    print('无解')
else:
    print('出现其他情况')

输出结果为:其输出结果所代表的含义为工人1在工位3上加工工序1,2。

求得该问题最优解为:
3801.35
工人1分配情况:
     工位1  工位2  工位3
工序1    0    0    1
工序2    0    0    1
工序3    0    0    0
工序4    0    0    0
工序5    0    0    0
工人2分配情况:
     工位1  工位2  工位3
工序1    0    0    0
工序2    0    0    0
工序3    0    0    0
工序4    0    1    0
工序5    0    0    0
工人3分配情况:
     工位1  工位2  工位3
工序1    0    0    0
工序2    0    0    0
工序3    1    0    0
工序4    0    0    0
工序5    1    0    0
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TUUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值