You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python DataFrame订单与卷材分配问题求助:代码逻辑修正

卷材订单分配逻辑修正

问题背景

现有两个DataFrame,分别存储订单详情和卷材(coil)详情,需完成订单到卷材的分配,满足以下规则:

  • 每个订单对分配的卷材重量有**最小(TOP_MIN_COIL_WT)和最大(TOP_MAX_COIL_WT)**范围限制,分配的单份卷材重量必须落在该区间内
  • 允许超额10%分配订单需求,以充分利用卷材

订单DataFrame(order为唯一ID)

order   bct  TOP_MIN_COIL_WT  TOP_MAX_COIL_WT  demand
0     o1  bct2                3               25    12.000
1     o2  bct2                3               25    11.340
2     o3  bct2                3               25    9.460
3     o4  bct2                3               25    6.540
4     o5  bct1                4                7    51.000
5     o6  bct1                5                7    51.000
6     o7  bct1                3                5    34.000
7     o8  bct1                3                5    22.260
8     o9  bct1                4                6    17.000
9    o10  bct1                5                7    17.000
10   o11  bct1                3                5    17.000
11   o12  bct1                4                7    6.605

卷材DataFrame(mc为唯一编号)

mc   bct  coiltons
0    c1  bct2     24.45
1    c2  bct2     24.10
2    c3  bct1     17.08
3    c4  bct1     17.04
4    c5  bct1     17.03
5    c6  bct1     17.01
6    c7  bct1     16.98
7    c8  bct1     16.98
8    c9  bct1     15.88
9   c10  bct1     15.76
10  c11  bct1     15.72
11  c12  bct1     15.65
12  c13  bct1     15.59
13  c14  bct1     13.16
14  c15  bct1     13.14

现有代码问题分析

原代码的核心问题集中在splitNumber函数逻辑错误和分配流程的不合理:

  1. splitNumber函数逻辑混乱:
    • 初始判断条件错误,未正确区分卷材重量是否符合范围
    • 拆分份数的计算范围搞反,导致无法找到有效拆分份数
    • 未处理无法拆分的情况(返回0),导致无效分配
  2. 分配流程问题:
    • 拆分卷材时错误地生成多份记录,但仅扣除一份的重量,剩余卷材的处理逻辑缺失
    • 未实现超额10%分配的规则
    • 迭代时直接修改原DataFrame,可能导致后续迭代数据异常

修正后的代码

import numpy as np
import pandas as pd
import math

def splitNumber(n, a, b):
    # 卷材重量小于最小允许值,无法满足要求,返回0(不能拆分/使用)
    if n < a:
        return 0
    # 卷材重量在允许范围内,无需拆分,返回1
    if a <= n <= b:
        return 1
    # 计算有效拆分份数的范围:i需满足 n/b < i < n/a
    min_i = math.ceil(n / b)
    max_i = math.floor(n / a)
    # 范围无效,无法拆分
    if min_i > max_i:
        return 0
    # 从大到小找最大有效份数(优先拆分更多小份,提升利用率)
    for i in range(max_i, min_i - 1, -1):
        part_weight = n / i
        if a <= part_weight <= b:
            return i
    # 无有效拆分方式
    return 0

# 复制卷材DataFrame,避免修改原数据
dfmc_copy = dfmc.copy().reset_index(drop=True)
outputRows = []

for _, order_row in dfo.iterrows():
    order_id = order_row['order']
    bct_type = order_row['bct']
    min_coil_wt = order_row['TOP_MIN_COIL_WT']
    max_coil_wt = order_row['TOP_MAX_COIL_WT']
    demand = order_row['demand']
    # 允许超额10%分配
    max_alloc = demand * 1.1
    remaining_demand = demand

    # 筛选当前bct类型且剩余重量>0的卷材
    available_coils = dfmc_copy[(dfmc_copy['bct'] == bct_type) & (dfmc_copy['coiltons'] > 0.001)].reset_index(drop=True)
    
    for _, coil_row in available_coils.iterrows():
        coil_id = coil_row['mc']
        coil_weight = coil_row['coiltons']
        coil_idx = dfmc_copy[dfmc_copy['mc'] == coil_id].index[0]

        if remaining_demand <= 0:
            break

        # 卷材重量符合订单范围,直接分配
        if min_coil_wt <= coil_weight <= max_coil_wt:
            # 计算可分配量:不超过剩余需求,也不超过超额上限
            alloc = min(remaining_demand, coil_weight, max_alloc - (demand - remaining_demand))
            outputRows.append([
                order_id, bct_type, coil_id, alloc, coil_weight, 0
            ])
            # 更新剩余需求和卷材重量
            remaining_demand -= alloc
            dfmc_copy.at[coil_idx, 'coiltons'] = coil_weight - alloc
            continue
        
        # 需要拆分卷材
        split_count = splitNumber(coil_weight, min_coil_wt, max_coil_wt)
        if split_count == 0:
            continue  # 无法拆分,跳过该卷材
        
        part_weight = coil_weight / split_count
        # 计算可分配量:不超过剩余需求、单份重量,且不超过超额上限
        alloc = min(remaining_demand, part_weight, max_alloc - (demand - remaining_demand))
        # 记录分配(仅当前订单使用的那一份)
        outputRows.append([
            order_id, bct_type, f"{coil_id}_1", alloc, coil_weight, 1
        ])
        # 更新剩余需求和卷材重量
        remaining_demand -= alloc
        dfmc_copy.at[coil_idx, 'coiltons'] = coil_weight - alloc

outputColumns = ['order', 'typebc', 'coil', 'allocatedQuantity', 'ton', 'flag']
df_output = pd.DataFrame(outputRows, columns=outputColumns)

修正说明

  1. splitNumber函数优化:
    • 明确判断逻辑,先排除无法使用的卷材
    • 正确计算拆分份数的有效范围,确保每份重量落在订单要求区间内
    • 返回0表示无法拆分,避免无效分配
  2. 分配流程优化:
    • 复制卷材DataFrame,避免修改原始数据影响后续操作
    • 实现超额10%分配规则,限制总分配量不超过需求的110%
    • 拆分卷材时仅记录当前订单使用的部分,剩余卷材重量保留在DataFrame中待后续订单分配
    • 筛选可用卷材时增加重量阈值(>0.001),避免处理几乎为空的卷材

内容的提问来源于stack exchange,提问作者Manglu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:44:50