fix: cal_x_task_count bug
This commit is contained in:
parent
98d76424c7
commit
cb1b2dfae6
|
@ -15,35 +15,51 @@ class PmService:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cal_x_task_count(cls, target_materialId:str, target_quantity, route_qs):
|
def cal_x_task_count(cls, target_materialId:str, target_quantity, route_qs):
|
||||||
# 构建逆向依赖图 {输出物料: [所有能生产它的工序]}
|
# 构建逆向依赖图 {输出物料ID: [Route]}
|
||||||
graph = defaultdict(list)
|
graph = defaultdict(list)
|
||||||
for route in route_qs:
|
for route in route_qs:
|
||||||
|
if route.material_out: # 确保输出物料存在
|
||||||
graph[route.material_out.id].append(route)
|
graph[route.material_out.id].append(route)
|
||||||
|
|
||||||
# 存储每个Route记录的生产数量 {route_id: 需生产数量}
|
# 存储每个物料的需求量
|
||||||
|
demands = defaultdict(float)
|
||||||
|
demands[target_materialId] = target_quantity
|
||||||
step_production = defaultdict(int)
|
step_production = defaultdict(int)
|
||||||
|
|
||||||
# 广度优先逆向遍历(BFS)
|
# 逆向遍历,从目标物料开始
|
||||||
queue = deque([(target_materialId, target_quantity)])
|
queue = deque([target_materialId])
|
||||||
while queue:
|
while queue:
|
||||||
current_material, current_demand = queue.popleft()
|
current_out_id = queue.popleft()
|
||||||
for route in graph.get(current_material, []):
|
current_demand = demands.get(current_out_id, 0)
|
||||||
# 根据工序类型计算当前工序的生产量
|
if current_demand <= 0:
|
||||||
if route.process.mtype == 20: # 拆分
|
continue
|
||||||
production = current_demand * route.div_number / (route.out_rate / 100)
|
|
||||||
elif route.process.mtype == 30: # 合并
|
|
||||||
production = current_demand / route.div_number / (route.out_rate / 100)
|
|
||||||
else: # 正常
|
|
||||||
production = current_demand / (route.out_rate / 100)
|
|
||||||
|
|
||||||
# 记录当前工序的生产量(向上取整)
|
# 处理所有能生产该物料的Route(多路径时需求均分)
|
||||||
step_production[route.id] = math.ceil(production)
|
routes = graph.get(current_out_id, [])
|
||||||
|
if not routes:
|
||||||
|
continue
|
||||||
|
|
||||||
# 将输入物料需求加入队列
|
# 均分需求到所有Route(示例按均分逻辑,可根据业务调整)
|
||||||
|
demand_per_route = math.ceil(current_demand / len(routes)) if len(routes) > 1 else current_demand
|
||||||
|
|
||||||
|
for route in routes:
|
||||||
|
# 记录该Route的产出量(向上取整)
|
||||||
|
step_production[route.id] = math.ceil(demand_per_route)
|
||||||
|
|
||||||
|
# 根据工序类型计算输入需求
|
||||||
|
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.material_in:
|
if route.material_in:
|
||||||
queue.append((route.material_in.id, production))
|
demands[route.material_in.id] += input_needed
|
||||||
|
queue.append(route.material_in.id)
|
||||||
|
|
||||||
return dict(step_production)
|
return dict(reversed(step_production.items()))
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
Loading…
Reference in New Issue