fix: cal_x_task_count分配任务数的bug
This commit is contained in:
parent
15ccfbe6f9
commit
8068cb1ca3
|
@ -14,54 +14,77 @@ from collections import defaultdict, deque
|
|||
class PmService:
|
||||
|
||||
@classmethod
|
||||
def cal_x_task_count(cls, target_materialId:str, target_quantity, route_qs):
|
||||
# 构建逆向依赖图 {输出物料ID: [Route]}
|
||||
def cal_x_task_count(cls, target_materialId: str, target_quantity, route_qs):
|
||||
# 构建逆向依赖图 {输出物料ID: [生产该物料的Route]}
|
||||
graph = defaultdict(list)
|
||||
graphin = defaultdict(list)
|
||||
for route in route_qs:
|
||||
if route.material_out: # 确保输出物料存在
|
||||
graph[route.material_out.id].append(route)
|
||||
if route.material_in: # 确保输入物料存在
|
||||
graphin[route.material_in.id].append((route, False))
|
||||
|
||||
# 存储每个物料的需求量
|
||||
demands = defaultdict(float)
|
||||
demands[target_materialId] = target_quantity
|
||||
step_production = defaultdict(int)
|
||||
|
||||
# 逆向遍历,从目标物料开始
|
||||
# 逆向遍历队列,从目标物料开始
|
||||
queue = deque([target_materialId])
|
||||
visited = set() # 防止重复处理
|
||||
|
||||
while queue:
|
||||
current_out_id = queue.popleft()
|
||||
if current_out_id in visited:
|
||||
continue
|
||||
visited.add(current_out_id)
|
||||
|
||||
current_demand = demands.get(current_out_id, 0)
|
||||
if current_demand <= 0:
|
||||
continue
|
||||
|
||||
# 处理所有能生产该物料的Route(多路径时需求均分)
|
||||
# 获取生产该物料的所有Route
|
||||
routes = graph.get(current_out_id, [])
|
||||
if not routes:
|
||||
continue
|
||||
continue # 无生产路线,无法继续逆向
|
||||
|
||||
# 均分需求到所有Route(示例按均分逻辑,可根据业务调整)
|
||||
demand_per_route = math.ceil(current_demand / len(routes)) if len(routes) > 1 else current_demand
|
||||
# 平均分配需求到各Route(根据业务需求可能需要调整分配策略)
|
||||
routes_count = len(routes)
|
||||
base_demand = current_demand // routes_count
|
||||
remainder = current_demand % routes_count
|
||||
|
||||
for route in routes:
|
||||
# 记录该Route的产出量(向上取整)
|
||||
step_production[route.id] = math.ceil(demand_per_route)
|
||||
for i, route in enumerate(routes):
|
||||
# 分配任务数
|
||||
task_count = base_demand + 1 if i < remainder else base_demand
|
||||
step_production[route.id] = task_count # 累加任务数
|
||||
|
||||
# 根据工序类型计算输入需求
|
||||
if route.process.mtype == 20: # 拆分工序:1个输入拆成多个输出
|
||||
input_needed = demand_per_route / route.div_number / (route.out_rate / 100)
|
||||
elif route.process.mtype == 30: # 合并工序:多个输入合并为1个输出
|
||||
input_needed = demand_per_route * route.div_number / (route.out_rate / 100)
|
||||
else: # 正常工序
|
||||
input_needed = demand_per_route / (route.out_rate / 100)
|
||||
# 根据工序类型计算所需输入物料
|
||||
if route.process.mtype == 20: # 拆分工序
|
||||
input_needed = math.ceil(task_count / route.div_number / (route.out_rate / 100))
|
||||
elif route.process.mtype == 30: # 合并工序
|
||||
input_needed = math.ceil(task_count * route.div_number / (route.out_rate / 100))
|
||||
else: # 普通工序
|
||||
input_needed = math.ceil(task_count / (route.out_rate / 100))
|
||||
|
||||
# 更新上游物料需求
|
||||
# 更新输入物料需求并加入队列
|
||||
if route.material_in:
|
||||
demands[route.material_in.id] += input_needed
|
||||
queue.append(route.material_in.id)
|
||||
|
||||
return dict(reversed(step_production.items()))
|
||||
input_material_id = route.material_in.id
|
||||
demands[input_material_id] += input_needed
|
||||
for index, (route_in, _) in enumerate(graphin[input_material_id]):
|
||||
if route_in == route:
|
||||
graphin[input_material_id][index] = (route_in, True)
|
||||
can_append = True
|
||||
for route_in, caled in graphin[input_material_id]:
|
||||
if caled is False:
|
||||
can_append = False
|
||||
break
|
||||
if can_append:
|
||||
queue.append(input_material_id)
|
||||
|
||||
|
||||
# 返回各Route的任务数量
|
||||
return {route.id: step_production.get(route.id, 0) for route in route_qs}
|
||||
|
||||
@classmethod
|
||||
def cal_real_task_count(cls, count: int, rate_list):
|
||||
"""
|
||||
|
@ -236,6 +259,8 @@ class PmService:
|
|||
'is_count_utask': route.is_count_utask
|
||||
})
|
||||
elif schedule_type == 'to_mgroup':
|
||||
base_demand = count // mgroups_count
|
||||
remainder = count % mgroups_count
|
||||
for indx, mgroup in enumerate(mgroups):
|
||||
Mtask.objects.create(**{
|
||||
'route': route,
|
||||
|
@ -244,7 +269,7 @@ class PmService:
|
|||
'material_out': material_out,
|
||||
'material_in': material_in,
|
||||
'mgroup': mgroup,
|
||||
'count': math.ceil(count/mgroups_count),
|
||||
'count': base_demand + 1 if indx < remainder else base_demand,
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
'utask': utask,
|
||||
|
|
Loading…
Reference in New Issue