(1)决策树构建:
问题二旨在为企业生产过程的各个阶段做出决策,以实现利润最大化。先确定关键决策节点,构建决策树来梳理决策流程和可能的路径,然后通过计算不同路径的成本与收益。明确了四个关键决策节点,即零件 1 的质量检验、零件 2 的质量检验、最终产品的质量检验以及对于不合格成品的拆解处理。每个节点都有两种决策路径。对于不合格成品的处理存在反馈循环,通过构建决策树图像,能直观呈现决策系统运作情况。然后通过成本公式直接计算即可。
(2)构建蒙特卡洛模拟求解:
模拟过程---确立问题域,包括零件 1 和零件 2 的检测决策、成品的检测决策以及不合格成品的拆解决策---
构建模拟框架---决策变量为离散均匀分布,取值 0 或 1,概率各为 0.5;零件次品和成品次品率取固定值
确定样本容量---设定模拟次数为 1000 次,每次模拟迭代中,利用随机数生成函数生成决策变量的随机取值构建随机决策路径组合
执行模拟实验---基于生成的决策变量和给定参数值,按上述成本和收益计算公式计算每次模拟的各项成本和收益,进而计算利润并记录关键数据。
得出结果---能全面考虑不确定性因素和复杂决策路径找到最优决策方案并深入分析。
(3)基于蚁群算法优化
初始化设置:确定蚂蚁数量、信息素相关参数(如初始浓度、蒸发率、影响因子以及蚂蚁留下的信息素总量);构建基于决策变量的所有可能决策方案集合即解空间。即蚂蚁的所有可走路径。
迭代搜索过程:
蚂蚁路径选择:每只蚂蚁从初始状态依当前信息素浓度和启发式信息按概率公式选择下一步决策,构建完整决策方案。
目标函数计算与评价:计算蚂蚁构建的决策方案对应的利润值,以此评估方案优劣。
信息素更新:优质解路径信息素增加,引导后续蚂蚁探索,同时蒸发机制避免陷入局部最优。
终止条件判断:迭代次数,达到时结束搜索,输出最优决策方案及利润值。
和决策树的结果进行比较,相差不大,说明优化算法没有陷入到局部最优,找到全局最优。
(4)决策树绘制代码:
import pydotplus
# 构建决策树
def build_decision_tree():
dot = pydotplus.Dot(graph_type='graph')
# 零件1检测节点
part1_detect_node = pydotplus.Node("Part1: Detect", shape="box")
dot.add_node(part1_detect_node)
# 零件1不检测节点
part1_not_detect_node = pydotplus.Node("Part1: Not Detect", shape="box")
dot.add_node(part1_not_detect_node)
# 零件1检测结果节点(合格)
part1_detect_result_qualified_node = pydotplus.Node("Part1 Detection Result: Qualified", shape="box")
dot.add_node(part1_detect_result_qualified_node)
# 零件1检测结果节点(不合格)
part1_detect_result_unqualified_node = pydotplus.Node("Part1 Detection Result: Unqualified", shape="box")
dot.add_node(part1_detect_result_unqualified_node)
# 零件2检测节点
part2_detect_node = pydotplus.Node("Part2: Detect", shape="box")
dot.add_node(part2_detect_node)
# 零件2不检测节点
part2_not_detect_node = pydotplus.Node("Part2: Not Detect", shape="box")
dot.add_node(part2_not_detect_node)
# 零件2检测结果节点(合格)
part2_detect_result_qualified_node = pydotplus.Node("Part2 Detection Result: Qualified", shape="box")
dot.add_node(part2_detect_result_qualified_node)
# 零件2检测结果节点(不合格)
part2_detect_result_unqualified_node = pydotplus.Node("Part2 Detection Result: Unqualified", shape="box")
dot.add_node(part2_detect_result_unqualified_node)
# 成品检测节点
product_detection_node = pydotplus.Node("Product Detection", shape="box")
dot.add_node(product_detection_node)
# 成品检测结果节点(合格)
product_detect_result_qualified_node = pydotplus.Node("Product Detection Result: Qualified", shape="box")
dot.add_node(product_detect_result_qualified_node)
# 成品检测结果节点(不合格)
product_detect_result_unqualified_node = pydotplus.Node("Product Detection Result: Unqualified", shape="box")
dot.add_node(product_detect_result_unqualified_node)
# 用户接收节点(合格)
user_receive_qualified_node = pydotplus.Node("User Receives Product: Qualified", shape="box")
dot.add_node(user_receive_qualified_node)
# 用户接收节点(不合格)
user_receive_unqualified_node = pydotplus.Node("User Receives Product: Unqualified", shape="box")
dot.add_node(user_receive_unqualified_node)
# 零件检测决策节点
part_detection_node = pydotplus.Node("Part Detection", shape="box")
dot.add_node(part_detection_node)
# 零件1检测分支
part1_detect_branch = pydotplus.Edge(part_detection_node, part1_detect_node, label="Part1 Detect")
dot.add_edge(part1_detect_branch)
# 零件1不检测分支
part1_not_detect_branch = pydotplus.Edge(part_detection_node, part1_not_detect_node, label="Part1 Not Detect")
dot.add_edge(part1_not_detect_branch)
# 零件1检测后合格分支
part1_detect_qualified_branch = pydotplus.Edge(part1_detect_node, part1_detect_result_qualified_node,
label="Qualified")
dot.add_edge(part1_detect_qualified_branch)
# 零件1检测后不合格分支
part1_detect_unqualified_branch = pydotplus.Edge(part1_detect_node, part1_detect_result_unqualified_node,
label="Unqualified")
dot.add_edge(part1_detect_unqualified_branch)
# 零件1不检测后装配分支
part1_not_detect_assemble_branch = pydotplus.Edge(part1_not_detect_node, product_detection_node,
label="Assemble")
dot.add_edge(part1_not_detect_assemble_branch)
# 零件2检测分支
part2_detect_branch = pydotplus.Edge(part_detection_node, part2_detect_node, label="Part2 Detect")
dot.add_edge(part2_detect_branch)
# 零件2不检测分支
part2_not_detect_branch = pydotplus.Edge(part_detection_node, part2_not_detect_node, label="Part2 Not Detect")
dot.add_edge(part2_not_detect_branch)
# 零件2检测后合格分支
part2_detect_qualified_branch = pydotplus.Edge(part2_detect_node, part2_detect_result_qualified_node,
label="Qualified")
dot.add_edge(part2_detect_qualified_branch)
# 零件2检测后不合格分支
part2_detect_unqualified_branch = pydotplus.Edge(part2_detect_node, part2_detect_result_unqualified_node,
label="Unqualified")
dot.add_edge(part2_detect_unqualified_branch)
# 零件2不检测后装配分支
part2_not_detect_assemble_branch = pydotplus.Edge(part2_not_detect_node, product_detection_node,
label="Assemble")
dot.add_edge(part2_not_detect_assemble_branch)
# 从零件1检测合格后装配到成品检测的分支
part1_detect_qualified_to_product_detect_branch = pydotplus.Edge(part1_detect_result_qualified_node,
product_detection_node, label="Assemble")
dot.add_edge(part1_detect_qualified_to_product_detect_branch)
# 从零件2检测合格后装配到成品检测的分支
part2_detect_qualified_to_product_detect_branch = pydotplus.Edge(part2_detect_result_qualified_node,
product_detection_node, label="Assemble")
dot.add_edge(part2_detect_qualified_to_product_detect_branch)
# 成品检测合格分支
product_detect_qualified_branch = pydotplus.Edge(product_detection_node, product_detect_result_qualified_node,
label="Qualified")
dot.add_edge(product_detect_qualified_branch)
# 成品检测不合格分支
product_detect_unqualified_branch = pydotplus.Edge(product_detection_node, product_detect_result_unqualified_node,
label="Unqualified")
dot.add_edge(product_detect_unqualified_branch)
# 成品检测合格后用户接收合格分支
product_detect_qualified_to_user_qualified_branch = pydotplus.Edge(product_detect_result_qualified_node,
user_receive_qualified_node, label="Qualified")
dot.add_edge(product_detect_qualified_to_user_qualified_branch)
# 成品检测不合格后用户接收不合格分支
product_detect_unqualified_to_user_unqualified_branch = pydotplus.Edge(product_detect_result_unqualified_node,
user_receive_unqualified_node,
label="Unqualified")
dot.add_edge(product_detect_unqualified_to_user_unqualified_branch)
return dot
if __name__ == "__main__":
dot = build_decision_tree()
dot.write('decision_tree.png', format='png')
(5)决策树直接求解代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import rcParams
import os
# 解决中文显示问题
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False
def calculate_profit(N1, N2, W11, W12, W21, W22, W3, W4, W5, W6, S0, alpha1, alpha2, beta):
"""
计算利润
:param N1: 零件1的购买数量
:param N2: 零件2的购买数量
:param W11: 零件1的购买单价
:param W12: 零件2的购买单价
:param W21: 零件1的检测成本单价
:param W22: 零件2的检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W5: 成品拆解成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:param alpha1: 零件1的次品率
:param alpha2: 零件2的次品率
:param beta: 成品次品率
:return: 每种决策路径下的利润列表
"""
all_decisions = [
{'D11': 0, 'D12': 0, 'D2': 0, 'D3': 0},
{'D11': 1, 'D12': 0, 'D2': 0, 'D3': 0},
{'D11': 0, 'D12': 1, 'D2': 0, 'D3': 0},
{'D11': 1, 'D12': 1, 'D2': 0, 'D3': 0},
{'D11': 0, 'D12': 0, 'D2': 1, 'D3': 0},
{'D11': 1, 'D12': 0, 'D2': 1, 'D3': 0},
{'D11': 0, 'D12': 1, 'D2': 1, 'D3': 0},
{'D11': 1, 'D12': 1, 'D2': 1, 'D3': 0},
{'D11': 0, 'D12': 0, 'D2': 0, 'D3': 1},
{'D11': 1, 'D12': 0, 'D2': 0, 'D3': 1},
{'D11': 0, 'D12': 1, 'D2': 0, 'D3': 1},
{'D11': 1, 'D12': 1, 'D2': 0, 'D3': 1},
{'D11': 0, 'D12': 0, 'D2': 1, 'D3': 1},
{'D11': 1, 'D12': 0, 'D2': 1, 'D3': 1},
{'D11': 0, 'D12': 1, 'D2': 1, 'D3': 1},
{'D11': 1, 'D12': 1, 'D2': 1, 'D3': 1},
]
profits = []
for decisions in all_decisions:
D11, D12, D2, D3 = decisions['D11'], decisions['D12'], decisions['D2'], decisions['D3']
# 计算零件1的有效可装配数量
Q1 = N1 * (1 - alpha1 * D11)
# 计算零件2的有效可装配数量
Q2 = N2 * (1 - alpha2 * D12)
# 取两者中较小值作为实际用于装配成品的基础数量
min_quantity = min(Q1, Q2)
# 各项成本计算
# 零件购买成本
C1 = N1 * W11 + N2 * W12
# 零件检测成本
C2 = N1 * W21 * D11 + N2 * W22 * D12
# 成品装配成本
C3 = W3 * min_quantity
# 成品检测成本
C4 = W4 * D2 * min_quantity
# 成品拆解成本
C5 = W5 * beta * D3 * D2 * min_quantity
# 用户调换成本
C6 = W6 * (1 - D2) * beta * min_quantity
# 收益计算
S = S0 * (1 - D2) * (1 - beta) * min_quantity
# 利润计算
M = S - (C1 + C2 + C3 + C4 + C5 + C6)
profits.append(M)
return profits
# 情况1的数据
N1_1, N2_1 = 2000, 2000
W11_1, W12_1 = 4, 18
W21_1, W22_1 = 2, 3
W3_1, W4_1 = 6, 3
W5_1, W6_1 = 5, 6
S0_1 = 56
alpha1_1, alpha2_1 = 0.1, 0.1
beta_1 = 0.1
# 计算情况1不同决策路径的利润
profits_1 = calculate_profit(N1_1, N2_1, W11_1, W12_1, W21_1, W22_1, W3_1, W4_1, W5_1, W6_1, S0_1, alpha1_1, alpha2_1, beta_1)
print("情况1不同策略的成本情况:")
print(pd.DataFrame({
'决策路径': [f'路径{i + 1}' for i in range(len(profits_1))],
'利润': profits_1
}))
# 可视化情况1的结果并保存图像
plt.figure(figsize=(10, 6))
bar_color = 'skyblue'
bars_1 = plt.bar(range(len(profits_1)), profits_1, tick_label=[f'路径{i + 1}' for i in range(len(profits_1))],
color=bar_color)
plt.xlabel("决策路径", fontsize=12, color='black')
plt.ylabel("利润", fontsize=12, color='black')
plt.title("情况1不同决策路径的利润比较", fontsize=14, color='black')
plt.xticks(range(len(profits_1)), [f'路径{i + 1}' for i in range(len(profits_1))], fontsize=10, color='black',
rotation=45)
plt.yticks(fontsize=10, color='black')
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# for bar in bars_1:
# height = bar.get_height()
# plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
if not os.path.exists('images'):
os.makedirs('images')
image_path_1 = os.path.join('images', '情况1不同决策路径利润比较.png')
plt.savefig(image_path_1)
plt.show()
# 情况2的数据
N1_2, N2_2 = 2000, 2000
W11_2, W12_2 = 4, 18
W21_2, W22_2 = 2, 3
W3_2, W4_2 = 6, 3
W5_2, W6_2 = 5, 6
S0_2 = 56
alpha1_2, alpha2_2 = 0.2, 0.2
beta_2 = 0.2
# 计算情况2不同决策路径的利润
profits_2 = calculate_profit(N1_2, N2_2, W11_2, W12_2, W21_2, W22_2, W3_2, W4_2, W5_2, W6_2, S0_2, alpha1_2, alpha2_2, beta_2)
print("情况2不同策略的成本情况:")
print(pd.DataFrame({
'决策路径': [f'路径{i + 1}' for i in range(len(profits_2))],
'利润': profits_2
}))
# 可视化情况2的结果并保存图像
plt.figure(figsize=(10, 6))
bars_2 = plt.bar(range(len(profits_2)), profits_2, tick_label=[f'路径{i + 1}' for i in range(len(profits_2))],
color=bar_color)
plt.xlabel("决策路径", fontsize=12, color='black')
plt.ylabel("利润", fontsize=12, color='black')
plt.title("情况2不同决策路径的利润比较", fontsize=14, color='black')
plt.xticks(range(len(profits_2)), [f'路径{i + 1}' for i in range(len(profits_2))], fontsize=10, color='black',
rotation=45)
plt.yticks(fontsize=10, color='black')
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# for bar in bars_2:
# height = bar.get_height()
# plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
image_path_2 = os.path.join('images', '情况2不同决策路径利润比较.png')
plt.savefig(image_path_2)
plt.show()
# 情况3的数据
N1_3, N2_3 = 2000, 2000
W11_3, W12_3 = 4, 18
W21_3, W22_3 = 2, 3
W3_3, W4_3 = 6, 3
W5_3, W6_3 = 5, 30
S0_3 = 56
alpha1_3, alpha2_3 = 0.1, 0.1
beta_3 = 0.1
# 计算情况3不同决策路径的利润
profits_3 = calculate_profit(N1_3, N2_3, W11_3, W12_3, W21_3, W22_3, W3_3, W4_3, W5_3, W6_3, S0_3, alpha1_3, alpha2_3, beta_3)
print("情况3不同策略的成本情况:")
print(pd.DataFrame({
'决策路径': [f'路径{i + 1}' for i in range(len(profits_3))],
'利润': profits_3
}))
# 可视化情况3的结果并保存图像
plt.figure(figsize=(10, 6))
bars_3 = plt.bar(range(len(profits_3)), profits_3, tick_label=[f'路径{i + 1}' for i in range(len(profits_3))],
color=bar_color)
plt.xlabel("决策路径", fontsize=12, color='black')
plt.ylabel("利润", fontsize=12, color='black')
plt.title("情况3不同决策路径的利润比较", fontsize=14, color='black')
plt.xticks(range(len(profits_3)), [f'路径{i + 1}' for i in range(len(profits_3))], fontsize=10, color='black',
rotation=45)
plt.yticks(fontsize=10, color='black')
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# for bar in bars_3:
# height = bar.get_height()
# plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
image_path_3 = os.path.join('images', '情况3不同决策路径利润比较.png')
plt.savefig(image_path_3)
plt.show()
# 情况4的数据
N1_4, N2_4 = 2000, 2000
W11_4, W12_4 = 4, 18
W21_4, W22_4 = 1, 1
W3_4, W4_4 = 6, 2
W5_4, W6_4 = 5, 30
S0_4 = 56
alpha1_4, alpha2_4 = 0.2, 0.2
beta_4 = 0.2
# 计算情况4不同决策路径的利润
profits_4 = calculate_profit(N1_4, N2_4, W11_4, W12_4, W21_4, W22_4, W3_4, W4_4, W5_4, W6_4, S0_4, alpha1_4, alpha2_4, beta_4)
print("情况4不同策略的成本情况:")
print(pd.DataFrame({
'决策路径': [f'路径{i + 1}' for i in range(len(profits_4))],
'利润': profits_4
}))
# 可视化情况4的结果并保存图像
plt.figure(figsize=(10, 6))
bars_4 = plt.bar(range(len(profits_4)), profits_4, tick_label=[f'路径{i + 1}' for i in range(len(profits_4))],
color=bar_color)
plt.xlabel("决策路径", fontsize=12, color='black')
plt.ylabel("利润", fontsize=12, color='black')
plt.title("情况4不同决策路径的利润比较", fontsize=14, color='black')
plt.xticks(range(len(profits_4)), [f'路径{i + 1}' for i in range(len(profits_4))], fontsize=10, color='black',
rotation=45)
plt.yticks(fontsize=10, color='black')
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# for bar in bars_4:
# height = bar.get_height()
# plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
image_path_4 = os.path.join('images', '情况4不同决策路径利润比较.png')
plt.savefig(image_path_4)
plt.show()
# 情况5的数据
N1_5, N2_5 = 2000, 2000
W11_5, W12_5 = 4, 18
W21_5, W22_5 = 8, 1
W3_5, W4_5 = 6, 2
W5_5, W6_5 = 5, 10
S0_5 = 56
alpha1_5, alpha2_5 = 0.1, 0.2
beta_5 = 0.1
# 计算情况5不同决策路径的利润
profits_5 = calculate_profit(N1_5, N2_5, W11_5, W12_5, W21_5, W22_5, W3_5, W4_5, W5_5, W6_5, S0_5, alpha1_5, alpha2_5, beta_5)
print("情况5不同策略的成本情况:")
print(pd.DataFrame({
'决策路径': [f'路径{i + 1}' for i in range(len(profits_5))],
'利润': profits_5
}))
# 可视化情况5的结果并保存图像
plt.figure(figsize=(10, 6))
bar_color = 'skyblue'
bars_5 = plt.bar(range(len(profits_5)), profits_5, tick_label=[f'路径{i + 1}' for i in range(len(profits_5))],
color=bar_color)
plt.xlabel("决策路径", fontsize=12, color='black')
plt.ylabel("利润", fontsize=12, color='black')
plt.title("情况5不同决策路径的利润比较", fontsize=14, color='black')
plt.xticks(range(len(profits_5)), [f'路径{i + 1}' for i in range(len(profits_5))], fontsize=10, color='black',
rotation=45)
plt.yticks(fontsize=10, color='black')
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# for bar in bars_5:
# height = bar.get_height()
# plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
#
image_path_5 = os.path.join('images', '情况5不同决策路径利润比较.png')
plt.savefig(image_path_5)
plt.show()
# 情况6的数据
N1_6, N2_6 = 2000, 2000
W11_6, W12_6 = 4, 18
W21_6, W22_6 = 2, 3
W3_6, W4_6 = 6, 3
W5_6, W6_6 = 40, 10
S0_6 = 56
alpha1_6, alpha2_6 = 0.05, 0.05
beta_6 = 0.05
# 计算情况6不同决策路径的利润
profits_6 = calculate_profit(N1_6, N2_6, W11_6, W12_6, W21_6, W22_6, W3_6, W4_6, W5_6, W6_6, S0_6, alpha1_6, alpha2_6, beta_6)
print("情况6不同策略的成本情况:")
print(pd.DataFrame({
'决策路径': [f'路径{i + 1}' for i in range(len(profits_6))],
'利润': profits_6
}))
# 可视化情况6的结果并保存图像
plt.figure(figsize=(10, 6))
bars_6 = plt.bar(range(len(profits_6)), profits_6, tick_label=[f'路径{i + 1}' for i in range(len(profits_6))],
color=bar_color)
plt.xlabel("决策路径", fontsize=12, color='black')
plt.ylabel("利润", fontsize=12, color='black')
plt.title("情况6不同决策路径的利润比较", fontsize=14, color='black')
plt.xticks(range(len(profits_6)), [f'路径{i + 1}' for i in range(len(profits_6))], fontsize=10, color='black',
rotation=45)
plt.yticks(fontsize=10, color='black')
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# for bar in bars_6:
# height = bar.get_height()
# plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
image_path_6 = os.path.join('images', '情况6不同决策路径利润比较.png')
plt.savefig(image_path_6)
plt.show()
(6)蒙特卡洛模拟求解代码:
import os
import numpy as np
import random
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 情况数据
situations = [
(0.1, 4, 2, 0.1, 18, 3, 0.1, 6, 3, 56, 6, 5),
(0.2, 4, 2, 0.2, 18, 3, 0.2, 6, 3, 56, 6, 5),
(0.1, 4, 2, 0.1, 18, 3, 0.1, 6, 3, 56, 30, 5),
(0.2, 4, 1, 0.2, 18, 1, 0.2, 6, 2, 56, 30, 5),
(0.1, 4, 8, 0.2, 18, 1, 0.1, 6, 2, 56, 10, 5),
(0.05, 4, 2, 0.05, 18, 3, 0.05, 6, 3, 56, 10, 40)
]
# 蚂蚁数量
ant_num = 50
# 最大迭代次数
max_iterations = 100
# 信息素蒸发率
rho = 0.1
# 信息素重要程度因子
alpha = 1
# 启发式信息重要程度因子
beta = 2
# 蚂蚁留下的信息素总量
Q = 100
# 零件1和零件2购买数量
N1 = 2000
N2 = 2000
# 假设已经有以下函数来计算成本和收益,这里只是占位,你需要根据实际情况完善
def calculate_costs_and_revenue(decision_vars, alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0):
"""
根据决策变量(如零件检测决策、成品检测决策等)以及相关成本、收益参数计算成本和收益
:param decision_vars: 决策变量字典,包含 'D11', 'D12', 'D2', 'D3' 键值对
:param alpha1: 零件1次品率
:param alpha2: 零件2次品率
:param beta: 成品次品率
:param W11: 零件1购买单价
:param W12: 零件2购买单价
:param W21: 零件1检测成本单价
:param W22: 零件2检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:return: 总成本 cost 和总收益 revenue
"""
D11, D12, D2, D3 = decision_vars['D11'], decision_vars['D12'], decision_vars['D2'], decision_vars['D3']
# 计算零件1的有效可装配数量
Q1 = N1 * (1 - alpha1 * D11)
# 计算零件2的有效可装配数量
Q2 = N2 * (1 - alpha2 * D12)
# 取两者中较小值作为实际用于装配成品的基础数量
min_quantity = min(Q1, Q2)
# 各项成本计算
# 零件购买成本
C1 = N1 * W11 + N2 * W12
# 零件检测成本
C2 = N1 * W21 * D11 + N2 * W22 * D12
# 成品装配成本
C3 = W3 * min_quantity
# 成品检测成本
C4 = W4 * D2 * min_quantity
# 成品拆解成本
C5 = 0 # 暂时先按不拆解考虑成本为0,实际可按具体逻辑完善
# 用户调换成本
C6 = W6 * (1 - D2) * beta * min_quantity
# 收益计算
S = S0 * (1 - D2) * (1 - beta) * min_quantity
# 总成本和总收益
cost = C1 + C2 + C3 + C4 + C5 + C6
revenue = S
return cost, revenue
# 初始化信息素矩阵
def init_pheromone_matrix():
return np.ones((2, 2, 2, 2)) # 对应四元组决策变量的每种组合,初始化为1
# 蚂蚁选择路径(构建决策方案)
def select_path(ant, pheromone_matrix, alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0):
"""
根据蚁群算法的路径选择概率逻辑,让蚂蚁基于信息素浓度和启发式信息选择下一个决策路径(构建决策方案)
:param ant: 当前蚂蚁编号(在本示例中暂未用到,但蚁群算法完整实现可能会需要)
:param pheromone_matrix: 信息素矩阵,记录了不同决策变量组合对应的信息素浓度
:param alpha1: 零件1次品率
:param alpha2: 零件2次品率
:param beta: 成品次品率
:param W11: 零件1购买单价
:param W12: 零件2购买单价
:param W21: 零件1检测成本单价
:param W22: 零件2检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:return: 蚂蚁选择的决策变量字典,包含 'D11', 'D12', 'D2', 'D3' 键值对
"""
# 初始化概率总和及转移概率字典(以四元组决策组合为键)
sum_probability = 0
transition_probabilities = {}
# 构建所有可能的下一个决策状态(遍历所有决策变量组合)
for D11_next in range(2):
for D12_next in range(2):
for D2_next in range(2):
for D3_next in range(2):
# 获取当前路径对应的信息素浓度
tau_ij = pheromone_matrix[D11_next][D12_next][D2_next][D3_next]
# 计算启发式信息(这里简单用成本的倒数来表示,成本越低越倾向选择,可根据实际调整)
cost, _ = calculate_costs_and_revenue({'D11': D11_next, 'D12': D12_next, 'D2': D2_next, 'D3': D3_next},
alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0)
eta_ij = 1 / (cost + 1e-5) # 加一个小值避免除0错误
# 按照蚁群算法概率计算公式计算概率分子部分
numerator = np.power(tau_ij, alpha) * np.power(eta_ij, beta)
# 记录当前转移的概率分子及对应的决策变量组合,后续用于计算最终概率
transition_probabilities[(D11_next, D12_next, D2_next, D3_next)] = numerator
# 累加所有可能选择的概率分子
sum_probability += numerator
# 计算每个可能转移的最终概率
final_probabilities = {key: p / sum_probability for key, p in transition_probabilities.items()}
# 随机选择一个决策状态,根据其概率决定是否选择该状态作为下一个决策
random_number = np.random.rand()
cumulative_probability = 0
for (D11_next, D12_next, D2_next, D3_next), prob in final_probabilities.items():
cumulative_probability += prob
if random_number < cumulative_probability:
decision_vars = {'D11': D11_next, 'D12': D12_next, 'D2': D2_next, 'D3': D3_next}
return decision_vars
# 计算路径概率(按照蚁群算法正规公式实现)
def calculate_path_probability(ant, current_city, pheromone_matrix, alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4,
W6, S0):
"""
根据蚁群算法的概率计算公式,计算蚂蚁从当前状态转移到下一个决策状态的概率
:param ant: 当前蚂蚁编号(在本示例中暂未用到,但蚁群算法完整实现可能会需要)
:param current_city: 当前决策状态(这里可理解为已经确定的部分决策变量组合,用四元组表示)
:param pheromone_matrix: 信息素矩阵,记录了不同决策变量组合对应的信息素浓度
:param alpha1: 零件1次品率
:param alpha2: 零件2次品率
:param beta: 成品次品率
:param W11: 零件1购买单价
:param W12: 零件2购买单价
:param W21: 零件1检测成本单价
:param W22: 零件2检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:return: 蚂蚁从当前决策状态转移到下一个决策状态的概率
"""
# 解包当前决策状态(四元组)
D11_current, D12_current, D2_current, D3_current = current_city
# 初始化概率总和及转移概率列表
sum_probability = 0
transition_probabilities = []
# 构建所有可能的下一个决策状态(遍历所有未确定的决策变量组合)
for D11_next in range(2):
for D12_next in range(2):
for D2_next in range(2):
for D3_next in range(2):
# 避免重复计算当前状态
if (D11_next, D12_next, D2_next, D3_next) == (D11_current, D12_current, D2_current, D3_current):
continue
# 获取当前路径对应的信息素浓度
tau_ij = pheromone_matrix[D11_next][D12_next][D2_next][D3_next]
# 计算启发式信息(这里简单用成本的倒数来表示,成本越低越倾向选择,可根据实际调整)
cost, _ = calculate_costs_and_revenue({'D11': D11_next, 'D12': D12_next, 'D2': D2_next, 'D3': D3_next},
alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0)
eta_ij = 1 / (cost + 1e-5) # 加一个小值避免除0错误
# 按照蚁群算法概率计算公式计算概率分子部分
numerator = np.power(tau_ij, alpha) * np.power(eta_ij, beta)
# 计算概率分母部分(累加所有可能选择的概率分子)
sum_probability += numerator
# 记录当前转移的概率分子,后续用于计算最终概率
transition_probabilities.append(numerator)
# 计算每个可能转移的最终概率
final_probabilities = [p / sum_probability for p in transition_probabilities]
# 随机选择一个决策状态,根据其概率决定是否选择该状态作为下一个决策
random_number = np.random.rand()
cumulative_probability = 0
for index, prob in enumerate(final_probabilities):
cumulative_probability += prob
if random_number < cumulative_probability:
# 将索引转换为对应的决策变量取值(四元组形式)
D11_next = index // 8 % 2
D12_next = index // 4 % 2
D2_next = index // 2 % 2
D3_next = index % 2
return D11_next, D12_next, D2_next, D3_next
# 更新信息素矩阵
def update_pheromone_matrix(pheromone_matrix, ants_decisions, ants_profits, rho, Q):
for i in range(len(ants_decisions)):
D11 = ants_decisions[i]['D11']
D12 = ants_decisions[i]['D12']
D2 = ants_decisions[i]['D2']
D3 = ants_decisions[i]['D3']
profit = ants_profits[i]
pheromone_matrix[D11][D12][D2][D3] = (1 - rho) * pheromone_matrix[D11][D12][D2][D3] + Q / (
profit + 1e-5) # 加一个小值避免除0错误
return pheromone_matrix
# 运行蚁群算法
def ant_colony_optimization():
best_profits = []
best_decision_desc = []
for situation in situations:
alpha1, W11, W21, alpha2, W12, W22, beta, W3, W4, S0, W6, W5 = situation
pheromone_matrix = init_pheromone_matrix()
best_profit = float('-inf')
best_decision_vars = None
for iteration in range(max_iterations):
ants_decisions = []
ants_profits = []
for ant in range(ant_num):
decision_vars = select_path(ant, pheromone_matrix, alpha1, alpha2, beta, W11, W12, W21, W22, W3,
W4, W6, S0)
cost, revenue = calculate_costs_and_revenue(decision_vars, alpha1, alpha2, beta, W11, W12, W21,
W22, W3, W4, W6, S0)
profit = revenue - cost
ants_decisions.append(decision_vars)
ants_profits.append(profit)
if profit > best_profit:
best_profit = profit
best_decision_vars = decision_vars
pheromone_matrix = update_pheromone_matrix(pheromone_matrix, ants_decisions, ants_profits, rho, Q)
best_profits.append(best_profit)
decision_desc = f"零件1检测:{best_decision_vars['D11']}, 零件2检测:{best_decision_vars['D12']}, " \
f"成品检测:{best_decision_vars['D2']}, 不合格成品拆解:{best_decision_vars['D3']}"
best_decision_desc.append(decision_desc)
return best_profits, best_decision_desc
best_profits, best_decision_desc = ant_colony_optimization()
# 输出每种情况的最优决策方案和利润值
for i in range(len(situations)):
print(f"情况{i + 1}:")
print(f"最优决策方案:{best_decision_desc[i]}")
print(f"最优利润值:{best_profits[i]}")
# 确保images文件夹存在,若不存在则创建
if not os.path.exists('images'):
os.makedirs('images')
# 绘制柱状图展示不同情况的最优利润(进行图像美化)
plt.figure(figsize=(10, 6)) # 设置合适的图形尺寸
# 自定义柱状图颜色,这里使用了一个比较美观的颜色列表,可根据喜好调整
bar_colors = plt.cm.Set1([i / len(best_profits) for i in range(len(best_profits))])
bars = plt.bar(range(len(best_profits)), best_profits, tick_label=[f'情况{i + 1}' for i in range(len(best_profits))],
color=bar_colors)
# 设置坐标轴标签字体大小和颜色
plt.xlabel('情况', fontsize=12, color='black')
plt.ylabel('最优利润', fontsize=12, color='black')
# 设置标题字体大小和颜色
plt.title('不同情况的最优利润对比(蚁群优化)', fontsize=14, color='black')
# 设置x轴刻度字体大小和颜色,并旋转刻度标签,使其更美观易读
plt.xticks(range(len(best_profits)), [f'情况{i + 1}' for i in range(len(best_profits))], fontsize=10, color='black',
rotation=45)
# 设置y轴刻度字体大小和颜色
plt.yticks(fontsize=10, color='black')
# 添加网格线,增强图像清晰度和规整性
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# 为柱状图添加数据标签,显示各情况对应的利润数值
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
# 保存图像到指定文件夹
image_path = os.path.join('images', '不同情况最优利润对比(蚁群优化).png')
plt.savefig(image_path)
# 显示图像
plt.show()
(7)蚁群算法求解代码:
import os
import numpy as np
import random
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 情况数据
situations = [
(0.1, 4, 2, 0.1, 18, 3, 0.1, 6, 3, 56, 6, 5),
(0.2, 4, 2, 0.2, 18, 3, 0.2, 6, 3, 56, 6, 5),
(0.1, 4, 2, 0.1, 18, 3, 0.1, 6, 3, 56, 30, 5),
(0.2, 4, 1, 0.2, 18, 1, 0.2, 6, 2, 56, 30, 5),
(0.1, 4, 8, 0.2, 18, 1, 0.1, 6, 2, 56, 10, 5),
(0.05, 4, 2, 0.05, 18, 3, 0.05, 6, 3, 56, 10, 40)
]
# 蚂蚁数量
ant_num = 50
# 最大迭代次数
max_iterations = 100
# 信息素蒸发率
rho = 0.1
# 信息素重要程度因子
alpha = 1
# 启发式信息重要程度因子
beta = 2
# 蚂蚁留下的信息素总量
Q = 100
# 零件1和零件2购买数量
N1 = 2000
N2 = 2000
# 假设已经有以下函数来计算成本和收益,这里只是占位,你需要根据实际情况完善
def calculate_costs_and_revenue(decision_vars, alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0):
"""
根据决策变量(如零件检测决策、成品检测决策等)以及相关成本、收益参数计算成本和收益
:param decision_vars: 决策变量字典,包含 'D11', 'D12', 'D2', 'D3' 键值对
:param alpha1: 零件1次品率
:param alpha2: 零件2次品率
:param beta: 成品次品率
:param W11: 零件1购买单价
:param W12: 零件2购买单价
:param W21: 零件1检测成本单价
:param W22: 零件2检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:return: 总成本 cost 和总收益 revenue
"""
D11, D12, D2, D3 = decision_vars['D11'], decision_vars['D12'], decision_vars['D2'], decision_vars['D3']
# 计算零件1的有效可装配数量
Q1 = N1 * (1 - alpha1 * D11)
# 计算零件2的有效可装配数量
Q2 = N2 * (1 - alpha2 * D12)
# 取两者中较小值作为实际用于装配成品的基础数量
min_quantity = min(Q1, Q2)
# 各项成本计算
# 零件购买成本
C1 = N1 * W11 + N2 * W12
# 零件检测成本
C2 = N1 * W21 * D11 + N2 * W22 * D12
# 成品装配成本
C3 = W3 * min_quantity
# 成品检测成本
C4 = W4 * D2 * min_quantity
# 成品拆解成本
C5 = 0 # 暂时先按不拆解考虑成本为0,实际可按具体逻辑完善
# 用户调换成本
C6 = W6 * (1 - D2) * beta * min_quantity
# 收益计算
S = S0 * (1 - D2) * (1 - beta) * min_quantity
# 总成本和总收益
cost = C1 + C2 + C3 + C4 + C5 + C6
revenue = S
return cost, revenue
# 初始化信息素矩阵
def init_pheromone_matrix():
return np.ones((2, 2, 2, 2)) # 对应四元组决策变量的每种组合,初始化为1
print("信息素初始矩阵:",init_pheromone_matrix())
# 蚂蚁选择路径(构建决策方案)
def select_path(ant, pheromone_matrix, alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0):
"""
根据蚁群算法的路径选择概率逻辑,让蚂蚁基于信息素浓度和启发式信息选择下一个决策路径(构建决策方案)
:param ant: 当前蚂蚁编号(在本示例中暂未用到,但蚁群算法完整实现可能会需要)
:param pheromone_matrix: 信息素矩阵,记录了不同决策变量组合对应的信息素浓度
:param alpha1: 零件1次品率
:param alpha2: 零件2次品率
:param beta: 成品次品率
:param W11: 零件1购买单价
:param W12: 零件2购买单价
:param W21: 零件1检测成本单价
:param W22: 零件2检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:return: 蚂蚁选择的决策变量字典,包含 'D11', 'D12', 'D2', 'D3' 键值对
"""
# 初始化概率总和及转移概率字典(以四元组决策组合为键)
sum_probability = 0
transition_probabilities = {}
# 构建所有可能的下一个决策状态(遍历所有决策变量组合)
for D11_next in range(2):
for D12_next in range(2):
for D2_next in range(2):
for D3_next in range(2):
# 获取当前路径对应的信息素浓度
tau_ij = pheromone_matrix[D11_next][D12_next][D2_next][D3_next]
# 计算启发式信息(这里简单用成本的倒数来表示,成本越低越倾向选择,可根据实际调整)
cost, _ = calculate_costs_and_revenue({'D11': D11_next, 'D12': D12_next, 'D2': D2_next, 'D3': D3_next},
alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0)
eta_ij = 1 / (cost + 1e-5) # 加一个小值避免除0错误
# 按照蚁群算法概率计算公式计算概率分子部分
numerator = np.power(tau_ij, alpha) * np.power(eta_ij, beta)
# 记录当前转移的概率分子及对应的决策变量组合,后续用于计算最终概率
transition_probabilities[(D11_next, D12_next, D2_next, D3_next)] = numerator
# 累加所有可能选择的概率分子
sum_probability += numerator
# 计算每个可能转移的最终概率
final_probabilities = {key: p / sum_probability for key, p in transition_probabilities.items()}
# 随机选择一个决策状态,根据其概率决定是否选择该状态作为下一个决策
random_number = np.random.rand()
cumulative_probability = 0
for (D11_next, D12_next, D2_next, D3_next), prob in final_probabilities.items():
cumulative_probability += prob
if random_number < cumulative_probability:
decision_vars = {'D11': D11_next, 'D12': D12_next, 'D2': D2_next, 'D3': D3_next}
return decision_vars
# 计算路径概率(按照蚁群算法正规公式实现)
def calculate_path_probability(ant, current_city, pheromone_matrix, alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4,
W6, S0):
"""
根据蚁群算法的概率计算公式,计算蚂蚁从当前状态转移到下一个决策状态的概率
:param ant: 当前蚂蚁编号(在本示例中暂未用到,但蚁群算法完整实现可能会需要)
:param current_city: 当前决策状态(这里可理解为已经确定的部分决策变量组合,用四元组表示)
:param pheromone_matrix: 信息素矩阵,记录了不同决策变量组合对应的信息素浓度
:param alpha1: 零件1次品率
:param alpha2: 零件2次品率
:param beta: 成品次品率
:param W11: 零件1购买单价
:param W12: 零件2购买单价
:param W21: 零件1检测成本单价
:param W22: 零件2检测成本单价
:param W3: 装配成本单价
:param W4: 成品检测成本单价
:param W6: 用户调换成本单价
:param S0: 每件合格品的收益
:return: 蚂蚁从当前决策状态转移到下一个决策状态的概率
"""
# 解包当前决策状态(四元组)
D11_current, D12_current, D2_current, D3_current = current_city
# 初始化概率总和及转移概率列表
sum_probability = 0
transition_probabilities = []
# 构建所有可能的下一个决策状态(遍历所有未确定的决策变量组合)
for D11_next in range(2):
for D12_next in range(2):
for D2_next in range(2):
for D3_next in range(2):
# 避免重复计算当前状态
if (D11_next, D12_next, D2_next, D3_next) == (D11_current, D12_current, D2_current, D3_current):
continue
# 获取当前路径对应的信息素浓度
tau_ij = pheromone_matrix[D11_next][D12_next][D2_next][D3_next]
# 计算启发式信息(这里简单用成本的倒数来表示,成本越低越倾向选择,可根据实际调整)
cost, _ = calculate_costs_and_revenue({'D11': D11_next, 'D12': D12_next, 'D2': D2_next, 'D3': D3_next},
alpha1, alpha2, beta, W11, W12, W21, W22, W3, W4, W6, S0)
eta_ij = 1 / (cost + 1e-5) # 加一个小值避免除0错误
# 按照蚁群算法概率计算公式计算概率分子部分
numerator = np.power(tau_ij, alpha) * np.power(eta_ij, beta)
# 计算概率分母部分(累加所有可能选择的概率分子)
sum_probability += numerator
# 记录当前转移的概率分子,后续用于计算最终概率
transition_probabilities.append(numerator)
# 计算每个可能转移的最终概率
final_probabilities = [p / sum_probability for p in transition_probabilities]
# 随机选择一个决策状态,根据其概率决定是否选择该状态作为下一个决策
random_number = np.random.rand()
cumulative_probability = 0
for index, prob in enumerate(final_probabilities):
cumulative_probability += prob
if random_number < cumulative_probability:
# 将索引转换为对应的决策变量取值(四元组形式)
D11_next = index // 8 % 2
D12_next = index // 4 % 2
D2_next = index // 2 % 2
D3_next = index % 2
return D11_next, D12_next, D2_next, D3_next
# 更新信息素矩阵
def update_pheromone_matrix(pheromone_matrix, ants_decisions, ants_profits, rho, Q):
for i in range(len(ants_decisions)):
D11 = ants_decisions[i]['D11']
D12 = ants_decisions[i]['D12']
D2 = ants_decisions[i]['D2']
D3 = ants_decisions[i]['D3']
profit = ants_profits[i]
pheromone_matrix[D11][D12][D2][D3] = (1 - rho) * pheromone_matrix[D11][D12][D2][D3] + Q / (
profit + 1e-5) # 加一个小值避免除0错误
return pheromone_matrix
# 运行蚁群算法
def ant_colony_optimization():
best_profits = []
best_decision_desc = []
for situation in situations:
alpha1, W11, W21, alpha2, W12, W22, beta, W3, W4, S0, W6, W5 = situation
pheromone_matrix = init_pheromone_matrix()
best_profit = float('-inf')
best_decision_vars = None
for iteration in range(max_iterations):
ants_decisions = []
ants_profits = []
for ant in range(ant_num):
decision_vars = select_path(ant, pheromone_matrix, alpha1, alpha2, beta, W11, W12, W21, W22, W3,
W4, W6, S0)
cost, revenue = calculate_costs_and_revenue(decision_vars, alpha1, alpha2, beta, W11, W12, W21,
W22, W3, W4, W6, S0)
profit = revenue - cost
ants_decisions.append(decision_vars)
ants_profits.append(profit)
if profit > best_profit:
best_profit = profit
best_decision_vars = decision_vars
pheromone_matrix = update_pheromone_matrix(pheromone_matrix, ants_decisions, ants_profits, rho, Q)
best_profits.append(best_profit)
decision_desc = f"零件1检测:{best_decision_vars['D11']}, 零件2检测:{best_decision_vars['D12']}, " \
f"成品检测:{best_decision_vars['D2']}, 不合格成品拆解:{best_decision_vars['D3']}"
best_decision_desc.append(decision_desc)
return best_profits, best_decision_desc
best_profits, best_decision_desc = ant_colony_optimization()
# 输出每种情况的最优决策方案和利润值
for i in range(len(situations)):
print(f"情况{i + 1}:")
print(f"最优决策方案:{best_decision_desc[i]}")
print(f"最优利润值:{best_profits[i]}")
# 确保images文件夹存在,若不存在则创建
if not os.path.exists('images'):
os.makedirs('images')
# 绘制柱状图展示不同情况的最优利润(进行图像美化)
plt.figure(figsize=(10, 6)) # 设置合适的图形尺寸
# 自定义柱状图颜色,这里使用了一个比较美观的颜色列表,可根据喜好调整
bar_colors = plt.cm.Set1([i / len(best_profits) for i in range(len(best_profits))])
bars = plt.bar(range(len(best_profits)), best_profits, tick_label=[f'情况{i + 1}' for i in range(len(best_profits))],
color=bar_colors)
# 设置坐标轴标签字体大小和颜色
plt.xlabel('情况', fontsize=12, color='black')
plt.ylabel('最优利润', fontsize=12, color='black')
# 设置标题字体大小和颜色
plt.title('不同情况的最优利润对比(蚁群优化)', fontsize=14, color='black')
# 设置x轴刻度字体大小和颜色,并旋转刻度标签,使其更美观易读
plt.xticks(range(len(best_profits)), [f'情况{i + 1}' for i in range(len(best_profits))], fontsize=10, color='black',
rotation=45)
# 设置y轴刻度字体大小和颜色
plt.yticks(fontsize=10, color='black')
# 添加网格线,增强图像清晰度和规整性
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# 为柱状图添加数据标签,显示各情况对应的利润数值
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width() / 2, height, f'{height:.2f}', ha='center', va='bottom', fontsize=10)
# 保存图像到指定文件夹
image_path = os.path.join('images', '不同情况最优利润对比(蚁群优化).png')
plt.savefig(image_path)
# 显示图像
plt.show()