2021 年数学建模竞赛题目D 题 连铸切割的在线优化

 

 

问题 1 

在满足基本要求和正常要求的条件下,依据尾坯长度制定出最优的

切割方案。假定用户目标值为 9.5 米,目标范围为 9.0~10.0 米,对以下尾坯长

度:109.0、93.4、80.9、72.0、62.7、52.5、44.9、42.7、31.6、22.7、14.5

和 13.7(单位:米),按“尾坯长度、切割方案、切割损失”等内容列表给出具

体的最优切割方案。

解析及代码

此问题主要关注如何制定最优的切割方案。最优的切割方案主要需要考虑满足用户的目标值,同时切割损失尽量小。首先,我们需要明确切割损失定义为报废钢坯的长度,用户的目标值范围为9.0至10.0米,用户目标值为9.5米。

在解决此问题时,我们需要先判断尾坯长度是否满足用户的目标值范围,如果满足则直接将其切割成用户所需长度,切割损失为0;否则我们需要考虑切割成最接近用户目标值的钢坯长度,同时使切割损失最小。

这是一个优化问题,可以使用数学模型或算法来求解。目前我们没有直接的解决方案,因为需要进一步的数学计算或编程。你可以利用数学规划(如整数线性规划)或贪心算法等方法来解决这个问题。

对于具体的尾坯长度,我们需要通过具体的计算或编程来得出最优的切割方案和切割损失。在进行这样的计算时,需要考虑尾坯长度、切割方案和切割损失三个要素。因此,这个问题需要更多的数学或编程背景来解决。

总的来说,我可以帮助你理解问题,并提供一些可能的解决方案,但具体的解决方案需要通过计算或编程来实现。如果你有具体的数学或编程问题,我很愿意帮助你解答。

function best_cut(tail_lengths)
    % 用户的目标值范围
    min_len = 9.0;
    max_len = 10.0;
    target_len = 9.5;
    tail_lengths = sort(tail_lengths,'descend');  % 降序排列尾坯长度
    for i = 1:length(tail_lengths)
        tail_len = tail_lengths(i);
        num_cuts = floor(tail_len / min_len);  % 最大可能的切割次数
        cut_lens = zeros(1,num_cuts);
        cut_loss = zeros(1,num_cuts);
        for j = 1:num_cuts
            % 从目标长度开始尝试
            proposed_cut = min(max_len, target_len);
            remaining_len = tail_len;
            total_loss = 0.0;
            total_cuts = 0;
            while total_cuts < j
                if proposed_cut <= remaining_len
                    remaining_len = remaining_len - proposed_cut;
                    total_cuts = total_cuts + 1;
                else
                    total_loss = total_loss + remaining_len;
                    break
                end
            end
            cut_lens(j) = proposed_cut;
            cut_loss(j) = total_loss;
        end
        [min_loss, idx] = min(cut_loss);
        fprintf('尾坯长度: %.1f 米, 切割方案: %.1f 米 x %d, 切割损失: %.1f 米\n', tail_len, cut_lens(idx), idx, min_loss);
    end
end

在 MATLAB 中使用时,只需调用 best_cut 函数并传入尾坯长度数组即可。例如,如果你想要测试你所提供的尾坯长度,你可以这样使用:

best_cut([109.0, 93.4, 80.9, 72.0, 62.7, 52.5, 44.9, 42.7, 31.6, 22.7, 14.5, 13.7]);

这将会为每个尾坯长度打印出最优的切割方案和切割损失。请注意,此代码只是一种可能的解决方案,可能需要根据实际情况进行调整。

问题 2

 在结晶器出现异常时,给出实时的最优切割方案:(1)在钢坯第 1

次出现报废段时,给出此段钢坯的切割方案;(2)在出现新的报废段后(如图 2),

给出新一段钢坯的切割方案和当前段钢坯切割的调整方案,或声明不作调整。

假设结晶器出现异常的时刻在 0.0、45.6、98.6、131.5、190.8、233.3、

266.0、270.7 和 327.9(单位:分钟),用户目标值是 9.5 米,目标范围是 9.0~10.0

米。在满足基本要求和正常要求的条件下,按“初始切割方案、调整后的切割方

案、切割损失”等内容列表给出这些时刻具体的最优切割方案。

解析及代码

% 用户目标值和目标范围
target = 9.5;
range = [9, 10];

% 结晶器出现异常的时间(单位:分钟)
abnormal_times = [0.0, 45.6, 98.6, 131.5, 190.8, 233.3, 266.0, 270.7, 327.9];

% 初始化切割方案和切割损失
cut_plan = cell(1, length(abnormal_times));
cut_loss = zeros(1, length(abnormal_times));

% 对于每个异常时间
for i = 1:length(abnormal_times)
    % 计算报废段长度(单位:米)
    scrap_length = abnormal_times(i);
    
    % 计算最佳切割方案和对应的切割损失
    [cut_plan{i}, cut_loss(i)] = get_best_cut_plan(scrap_length, target, range);
end

% 打印结果
for i = 1:length(abnormal_times)
    fprintf('初始切割方案: %s, 调整后的切割方案: %s, 切割损失: %.2f\n', ...
            num2str(abnormal_times(i)), num2str(cut_plan{i}), cut_loss(i));
end

function [best_plan, min_loss] = get_best_cut_plan(length, target, range)
    % 按照从小到大的顺序生成可能的切割长度
    possible_lengths = range(1):0.1:range(2);
    % 生成所有可能的切割方案
    possible_plans = combnk(possible_lengths, floor(length / range(1)));
    % 选择最佳切割方案(即切割损失最小的方案)
    [min_loss, idx] = min(abs(sum(possible_plans, 2) - length));
    best_plan = possible_plans(idx, :);
end

问题 3

 假设实时最优切割方案和结晶器出现异常的时刻均与问题 2 相同,

在满足基本要求和正常要求的条件下,对(

1)用户目标值是 8.5 米,目标范围

是 8.0~9.0 米,(

2)用户目标值是 11.1 米,目标范围是 10.6~11.6 米两种情况

分别按“初始切割方案、调整后的切割方案、切割损失”等内容给出具体的最优

切割方案

解析及代码

解决问题的关键在于确定最佳切割方案,其目标是最小化切割损失(报废钢坯的长度)并满足用户的目标值。

假设结晶器出现异常的时间在 0.0、45.6、98.6、131.5、190.8、233.3、266.0、270.7 和 327.9(单位:分钟),而拉坯的速度为1米/分钟。

下面是一个基于上述设定的Python代码,该代码可以找出最佳切割方案:

import numpy as np

# 用户目标值和目标范围
targets = [(8.5, [8.0, 9.0]), (11.1, [10.6, 11.6])]

# 结晶器出现异常的时间(单位:分钟)
abnormal_times = [0.0, 45.6, 98.6, 131.5, 190.8, 233.3, 266.0, 270.7, 327.9]

# 拉坯速度(单位:米/分钟)
pull_speed = 1

# 计算报废段长度
scrap_lengths = [time * pull_speed for time in abnormal_times]

for target, target_range in targets:
    print(f"\nUser target: {target}, Target range: {target_range}")

    for scrap_length in scrap_lengths:
        # 计算初始和调整后的切割方案以及切割损失
        initial_cut, adjusted_cut, cut_loss = get_best_cut_plan(scrap_length, target, target_range)
        print(f"Scrap length: {scrap_length:.1f}, Initial cut: {initial_cut}, Adjusted cut: {adjusted_cut}, Cut loss: {cut_loss:.1f}")

def get_best_cut_plan(scrap_length, target, target_range):
    # 计算可以切割的坯壳数量
    possible_cuts = int(scrap_length // target_range[0])

    # 计算初始和调整后的切割方案以及切割损失
    initial_cut = [target] * possible_cuts
    adjusted_cut = [target] * (possible_cuts - 1) + [scrap_length - target * (possible_cuts - 1)]
    cut_loss = scrap_length - sum(adjusted_cut)

    return initial_cut, adjusted_cut, cut_loss

此代码假设每个切割段的长度为目标值。当出现异常时,会从当前坯壳中切除一个长度等于报废段的部分,然后再进行必要的调整以满足用户的要求。如果最终的切割方案中的长度不在目标范围内,那么我们可以认为这是一个无法解决的情况,因为我们不能切割出长度小于目标范围下限或大于目标范围上限的坯壳。

这只是一个简化的示例,实际的情况可能会更复杂。例如,我们可能需要考虑切割机的能力(如切割速度和精度),以及切割过程中可能出现的误差。此外,也可能需要在多个目标之间做出权衡,比如最小化切割损失和满足用户需求。这可能会涉及到更复杂的数学模型或优化算法,例如动态规划或贪心算法。

猜你喜欢

转载自blog.csdn.net/m0_68036862/article/details/131650964