优化fix2_100的函数

This commit is contained in:
wangxu 2025-11-05 10:09:35 +08:00
parent 04996409da
commit a37039bce3
1 changed files with 40 additions and 39 deletions

View File

@ -1886,60 +1886,65 @@ def get_prev_cross(nodeid, area_id, roads_dir_dict):
return src_cross
def _to_int_list(nums, mask):
"""把非'-'位转成int再微调±1使总和=100只动最大位。"""
# 先全部转int
nums = [int(v) if not mask[i] else v for i, v in enumerate(nums)]
# 有效位下标
valid = [i for i, m in enumerate(mask) if not m]
if len(valid) < 2: # 单有效或全'-'无需调
return nums
s = sum(nums[i] for i in valid)
if s == 100:
return nums
# 差±1
delta = s - 100
idx_big = max(valid, key=nums.__getitem__) # 仍只动最大位
nums[idx_big] -= delta
return nums
def fix_to_100(a, b, c):
nums = [a, b, c]
dash_mask = [v == '-' for v in nums]
valid_idx = [i for i, m in enumerate(dash_mask) if not m]
mask = [v == '-' for v in nums]
valid_idx = [i for i, m in enumerate(mask) if not m]
# ----- 全 '-' -----
if len(valid_idx) == 0:
if not valid_idx:
return nums[:]
# ----- 仅 1 个有效 -----
if len(valid_idx) == 1:
vi = valid_idx[0]
nums[vi] = 100
return nums
nums[valid_idx[0]] = 100
return _to_int_list(nums, mask)
# ----- 2 个有效 -----
if len(valid_idx) == 2:
i0, i1 = valid_idx
v0, v1 = nums[i0], nums[i1]
# 只有出现 100 或 0 才强制随机拆分
if 100 in (v0, v1) or 0 in (v0, v1):
r1 = random.randint(1, 3)
r2 = 100 - r1
# 原 100 的下标放较大值,原 0 的下标放较小值
if v0 == 100 or v1 == 100: # 谁 100 谁拿大的
# 原100位放较大值原0位放较小值
if v0 == 100 or v1 == 100:
idx_100 = i0 if v0 == 100 else i1
idx_zro = i1 if v0 == 100 else i0
nums[idx_100] = max(r1, r2)
nums[idx_zro] = min(r1, r2)
else: # 谁 0 谁拿小的
else:
idx_zro = i0 if v0 == 0 else i1
idx_nz = i1 if v0 == 0 else i0
idx_nz = i1 if v0 == 0 else i0
nums[idx_zro] = min(r1, r2)
nums[idx_nz] = max(r1, r2)
return nums
# 正常值:等比缩放(下标不变)
nums[idx_nz] = max(r1, r2)
return _to_int_list(nums, mask) # 这里已int但保险再调一次
# 正常值:等比缩放
s = v0 + v1
if s == 100:
return nums
delta = s - 100 # 正=超出,负=不足
# 从值更大的下标里扣掉 delta
idx_big = i0 if v0 >= v1 else i1
nums[idx_big] -= delta
# Rounding 可能导致差 1再微调一次仍只动同一下标
delta2 = sum(nums[i] for i in valid_idx) - 100
nums[idx_big] -= delta2
return nums
nums[i0] = v0 * 100 / s
nums[i1] = v1 * 100 / s
return _to_int_list(nums, mask)
# ----- 3 个有效 -----
# 先处理 0/100只动原 100 或原 0 的下标)
if 100 in nums or 0 in nums:
# 100 存在:拆成两份 1~3只动 100 位与 0 位
if 100 in nums:
idx_100 = nums.index(100)
zeros = [i for i in range(3) if nums[i] == 0]
@ -1948,27 +1953,23 @@ def fix_to_100(a, b, c):
nums[zeros[0]] = r1
nums[zeros[1]] = r2
nums[idx_100] = 0 # 先清零,再走下面统一处理
# 现在只剩 0 需要修正
zeros = [i for i in range(3) if nums[i] == 0]
if len(zeros) == 1: # 单 0用 1~3 填充
if len(zeros) == 1:
nums[zeros[0]] = random.randint(1, 3)
elif len(zeros) == 2: # 双 0随机拆分 100只动 0 位
elif len(zeros) == 2:
r1 = random.randint(1, 3)
r2 = 100 - r1
nums[zeros[0]] = r1
nums[zeros[1]] = r2
return nums
return _to_int_list(nums, mask)
# 原本无 0/100等比缩放只动最大下标
# 正常缩放
s = sum(nums)
if s == 100:
return nums
return [int(v) for v in nums]
for i in range(3):
nums[i] = max(1, int(round(nums[i] * 100 / s)))
delta = sum(nums) - 100
idx_max = max(range(3), key=nums.__getitem__)
nums[idx_max] -= delta
return nums
nums[i] = max(1, round(nums[i] * 100 / s))
return _to_int_list(nums, mask)
def query_cross_delay_info_controller_export_excel(road_flow_delay_infos, road_flow_turn_rate):