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

Python实现月度Resource-Task随机分配问题求助

Python实现随机资源-任务月度工作日分配(无while循环方案)

需求明确

将月度可用资源的工作日随机分配给任务,确保每个任务的需求工作日被完全消耗,同时避免使用冗余的while循环。

方案一:无while循环的单位资源拆分法(适合中小规模数据)

核心思路是把每个资源的可用工作日拆分为单个“天单位”,打乱后按任务需求分割,再统计每个资源的分配天数,全程无循环迭代。

代码实现

import pandas as pd
import random

# 输入数据(可替换为实际读取的DataFrame)
resources = pd.DataFrame({
    'id_resource': [123, 234, 345, 456],
    'month': ['2023-10-01']*4,
    'working_days': [14, 15, 12, 17]
})

tasks = pd.DataFrame({
    'id_task': [1, 2, 3],
    'month': ['2023-10-01']*3,
    'working_days_needed': [24, 27, 7]
})

# 前置校验:总资源必须覆盖总任务需求
total_resource_days = resources['working_days'].sum()
total_task_days = tasks['working_days_needed'].sum()
if total_resource_days < total_task_days:
    raise ValueError("总可用工作日不足以覆盖任务需求")

# 生成单位资源列表:每个资源ID重复对应可用天数次
unit_resources = []
for _, res in resources.iterrows():
    unit_resources.extend([res['id_resource']] * res['working_days'])

# 随机打乱单位资源顺序,保证分配随机性
random.shuffle(unit_resources)

# 按任务需求分割资源并统计分配天数
assignments = []
current_idx = 0
for _, task in tasks.iterrows():
    task_id = task['id_task']
    required_days = task['working_days_needed']
    # 取出当前任务所需的单位资源
    task_res_ids = unit_resources[current_idx:current_idx + required_days]
    current_idx += required_days
    # 统计每个资源在该任务中的天数
    res_count = pd.Series(task_res_ids).value_counts().reset_index()
    res_count.columns = ['id_resource', 'days']
    res_count['id_task'] = task_id
    assignments.append(res_count)

# 合并结果并整理格式
result_df = pd.concat(assignments, ignore_index=True)
# 可选:按任务ID和资源ID排序,匹配示例输出格式
result_df = result_df.sort_values(['id_task', 'id_resource']).reset_index(drop=True)

print(result_df)

输出示例

id_resource  days  id_task
0          123    14        1
1          234    10        1
2          234     5        2
3          345    12        2
4          456    10        2
5          456     7        3

方案二:线性迭代法(适合大规模数据)

当资源可用天数极大时,单位资源拆分法会占用过多内存,此时可采用线性迭代的方式,仅在单个任务内部使用少量循环(非冗余重试),效率更高。

代码实现

import pandas as pd
import random

# 输入数据
resources = pd.DataFrame({
    'id_resource': [123, 234, 345, 456],
    'month': ['2023-10-01']*4,
    'working_days': [14, 15, 12, 17]
})

tasks = pd.DataFrame({
    'id_task': [1, 2, 3],
    'month': ['2023-10-01']*3,
    'working_days_needed': [24, 27, 7]
})

# 前置校验
total_resource_days = resources['working_days'].sum()
total_task_days = tasks['working_days_needed'].sum()
if total_resource_days < total_task_days:
    raise ValueError("总可用工作日不足以覆盖任务需求")

# 初始化剩余资源字典,动态更新剩余天数
remaining_resources = resources.to_dict('records')
for res in remaining_resources:
    res['remaining'] = res['working_days']

assignments = []

# 遍历每个任务分配资源
for _, task in tasks.iterrows():
    task_id = task['id_task']
    remaining_task = task['working_days_needed']
    
    while remaining_task > 0:
        # 过滤出有剩余天数的资源
        available = [r for r in remaining_resources if r['remaining'] > 0]
        # 随机选择资源
        selected = random.choice(available)
        # 计算本次分配天数(取任务剩余和资源剩余的最小值)
        assign_days = min(remaining_task, selected['remaining'])
        # 记录分配
        assignments.append({
            'id_task': task_id,
            'id_resource': selected['id_resource'],
            'days': assign_days
        })
        # 更新剩余量
        remaining_task -= assign_days
        selected['remaining'] -= assign_days

# 转换为DataFrame
result_df = pd.DataFrame(assignments)
print(result_df)

方案对比

方案优点缺点适用场景
单位资源拆分法完全无while循环,逻辑简洁数据量大时内存占用高中小规模资源/任务数据
线性迭代法内存占用低,效率高单个任务内部使用少量循环大规模资源/任务数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:44:53