优化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 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): def fix_to_100(a, b, c):
nums = [a, b, c] nums = [a, b, c]
dash_mask = [v == '-' for v in nums] mask = [v == '-' for v in nums]
valid_idx = [i for i, m in enumerate(dash_mask) if not m] valid_idx = [i for i, m in enumerate(mask) if not m]
# ----- 全 '-' ----- # ----- 全 '-' -----
if len(valid_idx) == 0: if not valid_idx:
return nums[:] return nums[:]
# ----- 仅 1 个有效 ----- # ----- 仅 1 个有效 -----
if len(valid_idx) == 1: if len(valid_idx) == 1:
vi = valid_idx[0] nums[valid_idx[0]] = 100
nums[vi] = 100 return _to_int_list(nums, mask)
return nums
# ----- 2 个有效 ----- # ----- 2 个有效 -----
if len(valid_idx) == 2: if len(valid_idx) == 2:
i0, i1 = valid_idx i0, i1 = valid_idx
v0, v1 = nums[i0], nums[i1] v0, v1 = nums[i0], nums[i1]
# 只有出现 100 或 0 才强制随机拆分
if 100 in (v0, v1) or 0 in (v0, v1): if 100 in (v0, v1) or 0 in (v0, v1):
r1 = random.randint(1, 3) r1 = random.randint(1, 3)
r2 = 100 - r1 r2 = 100 - r1
# 原 100 的下标放较大值,原 0 的下标放较小值 # 原100位放较大值原0位放较小值
if v0 == 100 or v1 == 100: # 谁 100 谁拿大的 if v0 == 100 or v1 == 100:
idx_100 = i0 if v0 == 100 else i1 idx_100 = i0 if v0 == 100 else i1
idx_zro = i1 if v0 == 100 else i0 idx_zro = i1 if v0 == 100 else i0
nums[idx_100] = max(r1, r2) nums[idx_100] = max(r1, r2)
nums[idx_zro] = min(r1, r2) nums[idx_zro] = min(r1, r2)
else: # 谁 0 谁拿小的 else:
idx_zro = i0 if v0 == 0 else i1 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_zro] = min(r1, r2)
nums[idx_nz] = max(r1, r2) nums[idx_nz] = max(r1, r2)
return nums return _to_int_list(nums, mask) # 这里已int但保险再调一次
# 正常值:等比缩放
# 正常值:等比缩放(下标不变)
s = v0 + v1 s = v0 + v1
if s == 100: nums[i0] = v0 * 100 / s
return nums nums[i1] = v1 * 100 / s
delta = s - 100 # 正=超出,负=不足 return _to_int_list(nums, mask)
# 从值更大的下标里扣掉 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
# ----- 3 个有效 ----- # ----- 3 个有效 -----
# 先处理 0/100只动原 100 或原 0 的下标)
if 100 in nums or 0 in nums: if 100 in nums or 0 in nums:
# 100 存在:拆成两份 1~3只动 100 位与 0 位
if 100 in nums: if 100 in nums:
idx_100 = nums.index(100) idx_100 = nums.index(100)
zeros = [i for i in range(3) if nums[i] == 0] 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[0]] = r1
nums[zeros[1]] = r2 nums[zeros[1]] = r2
nums[idx_100] = 0 # 先清零,再走下面统一处理 nums[idx_100] = 0 # 先清零,再走下面统一处理
# 现在只剩 0 需要修正
zeros = [i for i in range(3) if nums[i] == 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) nums[zeros[0]] = random.randint(1, 3)
elif len(zeros) == 2: # 双 0随机拆分 100只动 0 位 elif len(zeros) == 2:
r1 = random.randint(1, 3) r1 = random.randint(1, 3)
r2 = 100 - r1 r2 = 100 - r1
nums[zeros[0]] = r1 nums[zeros[0]] = r1
nums[zeros[1]] = r2 nums[zeros[1]] = r2
return nums return _to_int_list(nums, mask)
# 原本无 0/100等比缩放只动最大下标 # 正常缩放
s = sum(nums) s = sum(nums)
if s == 100: if s == 100:
return nums return [int(v) for v in nums]
for i in range(3): for i in range(3):
nums[i] = max(1, int(round(nums[i] * 100 / s))) nums[i] = max(1, round(nums[i] * 100 / s))
delta = sum(nums) - 100 return _to_int_list(nums, mask)
idx_max = max(range(3), key=nums.__getitem__)
nums[idx_max] -= delta
return nums
def query_cross_delay_info_controller_export_excel(road_flow_delay_infos, road_flow_turn_rate): def query_cross_delay_info_controller_export_excel(road_flow_delay_infos, road_flow_turn_rate):