朋友问到用算法解决化工生产设备动态投产问题【未完成留存】

一、背景

问题描述

  煤泥脱水是选煤生产重要的环节之一,通常采用加压过滤机和板框压滤机进行煤泥脱水作业。在实际生产中,煤泥通过浓缩池沉淀后,进入煤泥缓冲桶,并泵送至加压过滤机和板框压滤机进行处理。由于加压过滤机和板框压滤机处理能力不同,耗电量不同,为保证效益合理安排生产,效益最大化,需依据煤泥量,合理安排生产计划。
  已知,某选煤厂现有加压过滤机4台、板框压滤机2台。在实际生产时,加压过滤机持续上料,每90秒排料一次,小时处理量为30吨,板框压滤机每40分钟可以完成一次煤泥处理,其中排料需要3分钟,处理量为20吨,且两个板框压滤机不能同时排料。选煤厂在正常生产时,每小时产生的煤泥量将会在0到180吨之间。假设煤泥缓冲桶最大存储量为12吨,且煤泥缓冲桶泵送机构能够满足各台压滤机的需求。

  1. 请依据选煤厂生产煤泥产生情况,设计自动排程算法,用于指导选煤厂压滤机使用。
  2. 在选煤厂实际生产时,现场环境复杂,请考虑选煤厂环境下的工业限制条件,设计优化排程算法。

条件提取:

  • 系统入料速度 v i n p u t ∈ [ 0 , 4 ] t / m i n v_{input}\in[0,4] t/min vinput[0,4]t/min
  • 系统最大缓存 c o n t a i n e r = 12 t container=12t container=12t
  • 加压过滤机数量 n u m j y = 4 num_{jy}=4 numjy=4,来料消耗速度 v j y = 0.5 t / m i n v_{jy}=0.5 t/min vjy=0.5t/min,加料间隔 △ t j y = 0 m i n \triangle t_{jy}=0min tjy=0min
  • 板框压滤机数量 n u m b k = 2 num_{bk}=2 numbk=2,来料消耗速度 v b k = 0.5 t / m i n v_{bk}=0.5 t/min vbk=0.5t/min,加料间隔 △ t b k = 40 m i n \triangle t_{bk}=40min tbk=40min,两台板框压滤机启动时间限制 t l i m ∈ [ − 3 , 3 ] m i n t_{lim}\in[-3,3]min tlim[3,3]min
  • 题干中提到的耗电量、效益等工业其它限制条件均未明确,故不作考虑

方案探索思路:

  一般思路【输入 → 遍寻 \overset{遍寻}{\rightarrow} 遍寻输出 】:遍历输入 0 → 4 t / m i n 0\to 4 t/min 04t/min,比较每个输入条件下可能的输出组合,工作量大,缺乏明确的策略。
  我的思路【输出 → 覆盖 \overset{覆盖}{\rightarrow} 覆盖输入 】:输出可以找到相对明确的几套方案(14种组合,见下表),根据方案的线性组合,覆盖所有输出。

Combinationbk_01bk_02jy_01jy_02jy_03jy_04
A100000
B101000
C101100
D101110
E101111
F110000
G111000
H111100
I111110
J111111
K001000
L001100
M001110
N001111
  • 当入料速度 v i n p u t < 0.5 t / m i n v_{input}<0.5t/min vinput<0.5t/min时,启动一台能够连续进料的加压过滤机导致产能空转造成成本浪费,所以表格中优先考虑有一台间歇性运转的板框压滤机投入生产的情况;
  • 当入料速度平稳(包括稳定不变和稳定提升/下降)时,应当考虑加压过滤机的启停【优先考虑表格右半边】;
  • 当入料速度介稳时,应当先考虑板框压滤机启停来稳定来料速率对缓冲系统容积的冲击,再考虑加压过滤机的启停【先考虑表格左半边,再考虑表格右半边】;
  • 当需要两台板框压滤机共同投入生产时,注意两台机器之间的干涉;
  • 如果再偏向实际一点,设备启停切换应当设置合理的“弛豫”,避免来料速度和缓冲罐煤泥存量在单一切换条件附近震荡时,造成系统指引设备的频繁启停,引发生产混乱等
  • 总体要求:上述组合的工作特征曲线覆盖来料特征曲线,动态调节
  • TODO 不完美的地方待补充

二、尝试写代码

  注:以下代码只是某天下午想换一下头脑写下的未完成的代码。未来不知何时能够继续完成,但思路已成,如下代码如果能为有需求的人提供一个开头的帮助,也算是实现了价值。

2.1 导入库

import numpy as np
import matplotlib.pyplot as plt

2.2 定义设备类并实例化设备

class BanKuang:
	"""板框压滤机模型"""
	def __init__(self,v=0.5,tw=37,tb=3):
		"""初始化属性"""
		self.v = v # t/min
		self.time_work = tw # min
		self.time_break = tb # min
		
	def forward(self, t, t0=0, t_delta=0):
		"""
		板框压滤机消耗煤泥量随时间变化
		:param t: 时间(min)
		:param t0: 板框压滤机启用时刻(min)
		:param t_delta: 板框压滤机停机间隔(min)
		"""
		if (t - t0) % (self.time_break + self.time_work + t_delta) == 0:
			return self.v * (self.time_break + self.time_work)
		else:
			return 0

bk_01 = BanKuang()
bk_02 = BanKuang()

class JiaYa:
    """加压过滤机模型"""
    
    def __init__(self, v=0.5):
        """初始化属性"""
        
        self.v = v
        
    def forward(self, t, t0=0, t_delta=0):
        """
        加压过滤机消耗煤泥量随时间变化
        :param t: 时间(min)
        :param t0: 加压过滤机启用时刻(min)
        """
        
        return self.v * (t - t0)

jy_01 = JiaYa()
jy_02 = JiaYa()
jy_03 = JiaYa()
jy_04 = JiaYa()

2.3 定义多设备工作类

machine_dict = {'bk_01':bk_01,'bk_02':bk_02,'jy_01':jy_01,'jy_02':jy_02,'jy_03':jy_03,'jy_04':jy_04}

class MachineCombination:
    """多设备"""
    
    def __init__(self, t0, t_delta, names,**kwargs):
        """
        多台设备的工作量
        :param t0: 6台设备的各自启动时刻,type: Tuple, len(t0)=6,不启动则值为-1
        :param t_delta: 6台设备各自停机间隔,type: Tuple, len(t_delta)=6
        """
    
        self.t0 = t0
        self.t_delta = t_delta
        self.names = names
        self.machine_dict = kwargs
    
    def forward(self, t):
        """执行"""
        
        return [self.machine_dict[self.names[i]].forward(t, self.t0[i], self.t_delta[i]) for i in range(len(self.names))]

2.4 尝试组合并讨论

2.4.1 Combination A

Combinationbk_01bk_02jy_01jy_02jy_03jy_04
A100000
x = np.linspace(0,150,151)
bridge = [bk_01.forward(k) for k in x]
y = [sum(bridge[:t]) for t in range(len(bridge))]

plt.rcParams['font.sans-serif'] = ['simhei']

fig,(ax1,ax2,ax3,ax4) = plt.subplots(nrows=4, ncols=1, figsize=(12, 9), dpi=600)

ax1.plot(x, y, 'b.--')
ax1.set_xlabel('时刻 min')
ax1.set_ylabel('累计出料量 t')
ax1.set_title('一台板框压滤机工作')

ax2.plot(x, bridge, 'g.--')
ax2.set_xlabel('时刻 min')
ax2.set_ylabel('瞬时出料量 t')

test_b = [bk_01.forward(k, t0=10, t_delta=5) for k in x]
test_y = [sum(bridge[:t]) for t in range(len(bridge))]

ax3.plot(x, test_y, 'b.--')
ax3.set_xlabel('时刻 min')
ax3.set_ylabel('累计出料量 t')
ax3.set_title('一台板框压滤机工作(启动时刻t=10 min,停机间隔5 min)')

ax4.plot(x, test_b, 'g.--')
ax4.set_xlabel('时刻 min')
ax4.set_ylabel('瞬时出料量 t')

plt.tight_layout()

plt.show

Combination A

2.4.2 Combination F

Combinationbk_01bk_02jy_01jy_02jy_03jy_04
F110000
init_time_01 = (15, 18, -1, -1, -1, -1)  # 设置各设备启动时刻
break_time_01 = (0, 0, 0, 0, 0, 0, 0)  # 设置各设备工作间歇
ma_list_01 =('bk_01','bk_02')  # 设置需启动设备代号(名字)

# 实例化设备组合方案
combination_f01 = MachineCombination(init_time_01, break_time_01, ma_list_01, **machine_dict)

x2 = np.linspace(0,150,151)
# check_02 = [combination_f01.forward(k) for k in x2]
bridge2 = [sum(combination_f01.forward(k)) for k in x2]
y2 = [sum(bridge2[:t]) for t in range(len(bridge2))]

# 同组合,不同的启停方案
init_time_02 = (15, 18, -1, -1, -1, -1)
break_time_02 = (10, 33, 0, 0, 0, 0, 0)
ma_list_02 =('bk_01','bk_02')

combination_f02 = MachineCombination(init_time_02, break_time_02, ma_list_02, **machine_dict)

x3 = np.linspace(0,150,151)
# check_03 = [combination_f02.forward(k) for k in x3]
bridge3 = [sum(combination_f02.forward(k)) for k in x3]
y3 = [sum(bridge3[:t]) for t in range(len(bridge3))]

fig2, (ax21, ax22, ax23, ax24) = plt.subplots(nrows=4, ncols=1, figsize=(12, 9), dpi=600)

ax21.plot(x2, y2, 'b.--')
ax21.set_xlabel('时刻 min')
ax21.set_ylabel('累计出料量 t')
ax21.set_title('两台板框压滤机工作')

ax22.plot(x2, bridge2, 'g.--')
ax22.set_xlabel('时刻 min')
ax22.set_ylabel('瞬时出料量 t')

ax23.plot(x3, y3, 'b.--')
ax23.set_xlabel('时刻 min')
ax23.set_ylabel('累计出料量 t')
ax23.set_title('两台板框压滤机工作(启动时刻t=(15,18),停机间隔(10,33))')

ax24.plot(x3, bridge3, 'g.--')
ax24.set_xlabel('时刻 min')
ax24.set_ylabel('瞬时出料量 t')

plt.tight_layout()

plt.show

Combination F

TODO 组合和讨论待续

2.5 模拟一个稳定入料情况

import copy

def income(v):
    """煤泥入料累积量函数"""
    
    vv = copy.deepcopy(v)
    for i in range(len(vv)):
        if i == 0:
            continue
        else:
            vv[i] += vv[i-1]
    return vv

v = np.random.rand(151) * 0.7 + 0.33 # 煤泥进料瞬时速率
v_ic = income(v) # 煤泥累计

fig2, (ax21, ax22, ax23, ax24) = plt.subplots(nrows=4, ncols=1, figsize=(12, 9), dpi=600)

ax21.plot(x2, y2, 'b.--')
ax21.plot(x2, v_ic, 'r.--')
ax21.set_xlabel('时刻 min')
ax21.set_ylabel('累计出料量 t')
ax21.set_title('两台板框压滤机工作')

ax22.plot(x2, bridge2, 'g.--')
ax22.plot(x2, v, 'r.--')
ax22.set_xlabel('时刻 min')
ax22.set_ylabel('瞬时出料量 t')

ax23.plot(x3, y3, 'b.--')
ax23.plot(x3, v_ic, 'r.--')
ax23.set_xlabel('时刻 min')
ax23.set_ylabel('累计出料量 t')
ax23.set_title('两台板框压滤机工作(启动时刻t=(15,18),停机间隔(10,33))')

ax24.plot(x3, bridge3, 'g.--')
ax24.plot(x3, v, 'r.--')
ax24.set_xlabel('时刻 min')
ax24.set_ylabel('瞬时出料量 t')

plt.tight_layout()

plt.show

模拟一个稳定入料情况
  由图可知,应当提前两台板框压滤机的启动时刻,以满足最初入料,避免存量溢出;而后期则需适当调节两台设备的工作间隔,避免产能浪费。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值