问题描述¶
悬臂梁问题 由设计 I 型梁的横截面组成,以使梁在一定应力下不会变形或破坏的情况下获得最小体积。有关更多详细信息,请参阅 Wikipedia。我们记 L、H、h1、b1 和 b2 为梁的尺寸。
梁的体积由下式给出:
$V = f(H, h_1, b_1, b_2) = \left[2h_1b_1 + \left(H - 2h_1\right)b_2\right]L$
约束条件为:
梁根部处的最大弯曲应力,定义为:
$g_1(H, h_1, b_1, b_2) = \frac{P L H}{2I}$
梁尖端处的最大挠度,定义为:
$g_2(H, h_1, b_1, b_2) = \frac{P L^3}{3EI}$
学习要点¶
- 使用浮点变量表示连续尺寸,用整数索引选择离散尺寸。
- 使用模型数组按决策表达式查表。
- 将应力、挠度与体积写成表达式,添加约束并最小化体积。
建模思路¶
悬臂梁问题的 OptAgent 模型使用整型和浮点型决策变量。H、b1、b2 声明为浮点型决策变量,定义域分别为 [3.0, 7.0]、[2.0, 12.0] 和 [0.1, 2.0]。最后一个变量 h1 是离散的:它表示索引集合 {0, 1, ..., 7} 中的整数,通过数组查表映射到一组可行取值 {0.1, 0.26, 0.35, 0.5, 0.65, 0.75, 0.9, 1.0}。
弯曲应力、挠度和体积直接由模型表达式计算,转动惯量 I 是中间表达式。模型约束应力不超过 5000、挠度不超过 0.10,并最小化体积。
Python 实现¶
from pathlib import Path
from optagent import OptModel, solve
def main(output_file=None, time_limit=10):
load = 1000
elasticity = 10.0e6
length = 36
possible_values = [0.1, 0.26, 0.35, 0.5, 0.65, 0.75, 0.9, 1.0]
model = OptModel()
possible_values_array = model.array(possible_values)
height = model.float(3.0, 7.0)
h1_index = model.int(0, len(possible_values) - 1,
)
b1 = model.float(2.0, 12.0)
b2 = model.float(0.1, 2.0)
h1 = possible_values_array[h1_index]
inertia = (1.0 / 12.0) * b2 * (height - 2 * h1) ** 3 + 2 * (
(1.0 / 12.0) * b1 * h1**3 + b1 * h1 * (height - h1) ** 2 / 4.0
)
bending_stress = load * length * height / (2 * inertia)
tip_deflection = (load * length**3) * (3 * elasticity * inertia) ** -1
volume = (2 * h1 * b1 + (height - 2 * h1) * b2) * length
model.constraint(bending_stress <= 5000)
model.constraint(tip_deflection <= 0.10)
model.minimize(volume)
solution = solve(model, time_limit_s=float(time_limit))
result_values = {'volume': volume.value, 'height': height.value, 'h1': h1.value, 'b1': b1.value, 'b2': b2.value, 'bending_stress': bending_stress.value, 'tip_deflection': tip_deflection.value}
result_text = (
f"Status = {solution.feasible}; Volume = {result_values['volume']}\n"
f"H = {result_values['height']}\n"
f"h1 = {result_values['h1']}\n"
f"b1 = {result_values['b1']}\n"
f"b2 = {result_values['b2']}\n"
f"Bending stress = {result_values['bending_stress']}\n"
f"Tip deflection = {result_values['tip_deflection']}"
)
print(result_text)
if output_file is not None:
Path(output_file).write_text(result_text + "\n", encoding="utf-8")
return solution
本地运行¶
悬臂梁模型不需要外部实例文件,直接调用 main 即可;调整 time_limit 可以控制求解时间。
solution_cantilevered_beam = main(time_limit=1)