对于炉温曲线的优化主要是通过牛顿冷却定律来对回焊炉的温度以及过炉速度的控制研究最适的炉温曲线.
主要使用牛顿冷却定律的差分格式,其中
T
a
(
t
)
T_a(t)
Ta?(t)为t时刻的环境温度
T
(
t
+
Δ
t
)
?
T
(
t
)
Δ
t
=
k
[
T
a
(
t
)
?
T
(
t
)
]
\frac{T(t+\Delta t )-T(t)}{\Delta t} = k[T_a(t)-T(t)]
ΔtT(t+Δt)?T(t)?=k[Ta?(t)?T(t)]
环境温度
想要使用牛顿冷却定律首先要确定好环境温度的变化情况,本文对温区间的影响做简化处理,认为再小温区中前一温区最后5cm到后一温区5cm环境温度随空间距离线性变化
u
(
t
,
x
)
=
k
x
+
b
u(t,x) = kx+b
u(t,x)=kx+b 这其中
k
=
T
i
+
1
?
T
i
15
k=\frac{T_{i+1}-T_i}{15}
k=15Ti+1??Ti??
b
=
T
i
b=T_i
b=Ti?
通过模拟得到的环境温度如下
参数拟合
将K设定为关于位置的分段函数,分段通过最小二乘法拟合最优值. 通过对时间的差分,通过递推的方式从开始的25℃,不断向后计算每个0.5s的温度值,再将该值与附件中对应时间的温度值通过最小二乘法计算目标函数值.最小化该目标函数,不断修改k值大小.最终得到结果再整个模拟计算温度变化与 实验数据进行对比.计算R2来作为拟合度优劣的评判.
start = 0 #21 174 204 234 295
end = round(x0/V) #xk 温区边界点
Start = [0]*6
End = [x0,x1_5,x6,x7,x8_9,x10_]
for i in range(5):
Start[i+1] =round(End[i]/V)
K = []
Ylast = 25
# print(end)
for i in range(6):
start = Start[i]
end = round(End[i]/V)
X = np.linspace(start,end,(end-start)*2,endpoint=False)
# print(X[:-1])
y_true = data.loc[(data['时间']>=start) & (data['时间']<end),:]['温度']
delta_score =float('inf')
pre_score = float('inf')
i = 100
k = 0.3
bestk = 0
bestscore = float('inf')
bestkypred = None
while delta_score>1e-5 and i<10000:
ypred = Newton(X,k,Ylast,V)
score = np.sum((y_true-ypred[(X>=19).argmax():])**2,axis=0)
delta_score = abs(score-pre_score)
if score < bestscore:
bestscore = score
bestk = k
bestkypred=ypred
pre_score = score
i+=1
k = k - 1.0 / (i +1e3)
print(bestkypred[(X>=19).argmax():(X>=19).argmax()+10])
print(y_true.head(10))
print(bestscore)
print(bestk)
Ylast = bestkypred[-1]
K.append(bestk)
print(K)
得到的最终结果 计算R2>99.6%.
温区 | 炉前 | 温区1-5 | 温区6 | 温区7 | 温区8-9 | 温区10至炉后 |
---|
K | 0.01972, | 0.01767 | 0.01836 | 0.02386 | 0.02110 | 0.007446 |
结果求解
根据上述求出的k值,带入温度以及过炉速度计算出温度走势
#对比附件实验数据 计算R^2
# 问题一求解类似
K =[0.01972, 0.01767, 0.01836, 0.02386, 0.02110, 0.007446]
Start = [0]*6
End = [x0,x1_5,x6,x7,x8_9,x10_]
for i in range(5):
Start[i+1] =round(End[i]/V)
last = 25
Y_pred = []
Xlist = []
for i in range(6):
k = K[i]
start = Start[i]
end = round(End[i]/V)
X = np.linspace(start, end, (end - start) * 2 ,endpoint=False)
if i == 5:
X= np.append(X,np.array([X[-1]+0.5]))
ypred = Newton(X, k, last,V)
last = ypred[-1]
Y_pred.extend(ypred)
Xlist.extend(X)
Xlist = np.array(Xlist)
Y_pred = np.array(Y_pred)
# print(r2_score(data['温度'],Y_pred[(Xlist>=19).argmax():]))
plt.plot(Xlist,Y_pred,label='模拟温度')
plt.legend()
plt.show()
最优过炉速度确定
由于题目中的制程限制,通过代入各个小温区的温度参数进行对问题二的求解。在此过程中,我们对所要求的传送带速度进行了离散化处理,通过坐标下降计算各个速度值最终得到了传送带的最大的可行速度值。
从最大速度不断下降,只要不满足制程条件就继续继续下降计算,直到满足条件的第一个速度值即为所求
flag = -1
V = 100/60
for k in range(100,60,-1):
flag = -1
V = k/60
K =[0.01972, 0.01767, 0.01836, 0.02386, 0.02110, 0.007446]
Start = [0]*6
End = [x0,x1_5,x6,x7,x8_9,x10_]
for i in range(5):
Start[i+1] =round(End[i]/V)
last = 25
Y_pred = []
Xlist = []
for i in range(6):
k = K[i]
start = Start[i]
end = round(End[i]/V)
X = np.linspace(start, end, (end - start) * 2 ,endpoint=False)
if i == 5:
X= np.append(X,np.array([X[-1]+0.5]))
ypred = Newton(X, k, last,V)
if ypred.any()==False :
flag = 0
continue
last = ypred[-1]
Y_pred.extend(ypred)
Xlist.extend(X)
# if Y_pred == False:
# flag = 0
# continue
Xlist = np.array(Xlist)
Y_pred = np.array(Y_pred)
Y_pred_S = pd.Series(Y_pred)
Up_time = Y_pred_S[:Y_pred_S.argmax()].loc[(Y_pred_S >= 150) & (Y_pred_S <= 190)].shape[0] / 2
High_time = Y_pred_S.loc[Y_pred_S > 217].shape[0] / 2
Max_heat = Y_pred_S.max()
if Up_time>120 or Up_time<60:
flag = 0
continue
elif High_time>90 or High_time<40:
flag = 0
continue
elif Max_heat>250 or Max_heat<240:
flag = 0
continue
if flag == -1:
break
print(V*60)
问题三
通过单目标规划求解理想的炉温曲线
应使超过217oC到峰值温度所覆盖的面积最小,
决策参数分别由过炉速度以及每个温区的温度值,
约束条件为回焊炉的制程范围。
在满足该制程范围的条件下,使用粒子群算法(当然可以是其他的启发式搜索算法),
1.求解最优由于温度的范围为65-100cm/min,以及每个温区的温度变化范围为10℃,从而限制出搜索空间.
-
随机初始化100个粒子,迭代次数200次,. -
在粒子群算法中, 由于温度的范围为65-100cm/min,以及每个温区的温度变化范围为10℃,从而限制出搜索空间. -
随机初始化粒子数,经过若干次的迭代搜索求解出最合适的过炉速度以及每个可设定的温区值.
最终结果
参数 | 过炉速度 | 温区1-5 | 温区6 | 温区7 | 温区8-9 |
---|
值 | 94cm/min | 185℃ | 185℃ | 234℃ | 265℃ |
第四问使用多目标规划模型,然后将两个目标结合起来处理成单目标
最终也可以同样使用启发式算法进行搜索,但时间有限并没有算出最终答案😁
|