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
相关产品推荐
相关产品推荐

