fork download
  1. import random
  2. import statistics
  3.  
  4. def generate_exact_split():
  5. # 核心参数(严格锁定)
  6. TARGET_SUM = 99462 # 总和必须精确等于此值
  7. MULTIPLIER = 605
  8. split_parts = 11 # 16份拆分值
  9. MAX_PRODUCT = 10000 # 最大乘积不超过10000
  10. MIN_PRODUCT = 6000 # 最小乘积不低于6000
  11. precision = 1 # 1位小数
  12.  
  13. # 验证可行性
  14. if split_parts * MIN_PRODUCT > TARGET_SUM or split_parts * MAX_PRODUCT < TARGET_SUM:
  15. return f"无法拆分:16份需在[{split_parts*MIN_PRODUCT}, {split_parts*MAX_PRODUCT}]"
  16.  
  17. # 生成初始值(无规律,低重复)
  18. split_values = []
  19. value_counts = {}
  20.  
  21. while len(split_values) < split_parts:
  22. max_val = round(MAX_PRODUCT / MULTIPLIER, precision) # 16.3
  23. min_val = round(MIN_PRODUCT / MULTIPLIER, precision) # 9.8
  24. val = round(random.uniform(min_val, max_val), precision)
  25.  
  26. # 检查乘积范围
  27. product = round(val * MULTIPLIER)
  28. if not (MIN_PRODUCT <= product <= MAX_PRODUCT):
  29. continue
  30.  
  31. # 避免连续值(如x和x+0.1)
  32. has_consecutive = False
  33. for existing in split_values:
  34. if 0.1 <= abs(val - existing) <= 0.2:
  35. has_consecutive = True
  36. break
  37. if has_consecutive:
  38. continue
  39.  
  40. # 控制重复(最多2次)
  41. if value_counts.get(val, 0) < 2:
  42. split_values.append(val)
  43. value_counts[val] = value_counts.get(val, 0) + 1
  44.  
  45. # 调整总和至精确目标值
  46. products = [round(v * MULTIPLIER) for v in split_values]
  47. diff = TARGET_SUM - sum(products)
  48.  
  49. # 优先调整只出现1次的值
  50. single_indices = [i for i, v in enumerate(split_values) if value_counts[v] == 1]
  51. random.shuffle(single_indices)
  52.  
  53. for i in single_indices:
  54. if diff == 0:
  55. break
  56. step = 0.1 if diff > 0 else -0.1
  57. new_val = round(split_values[i] + step, precision)
  58. new_product = round(new_val * MULTIPLIER)
  59.  
  60. if (MIN_PRODUCT <= new_product <= MAX_PRODUCT and
  61. value_counts.get(new_val, 0) < 2):
  62.  
  63. old_val = split_values[i]
  64. value_counts[old_val] -= 1
  65. if value_counts[old_val] == 0:
  66. del value_counts[old_val]
  67.  
  68. split_values[i] = new_val
  69. products[i] = new_product
  70. value_counts[new_val] = value_counts.get(new_val, 0) + 1
  71. diff = TARGET_SUM - sum(products)
  72.  
  73. # 改进的最终调整逻辑:分散调整多个值以确保总和正确
  74. if diff != 0:
  75. # 打乱顺序,使调整更均匀
  76. indices = list(range(len(products)))
  77. random.shuffle(indices)
  78.  
  79. for i in indices:
  80. if diff == 0:
  81. break
  82.  
  83. # 计算当前值可以调整的最大步长
  84. current = products[i]
  85. max_possible = MAX_PRODUCT - current
  86. min_possible = MIN_PRODUCT - current
  87.  
  88. if diff > 0:
  89. # 需要增加总和,取可能的最大值
  90. step = min(diff, max_possible)
  91. else:
  92. # 需要减少总和,取可能的最小值
  93. step = max(diff, min_possible)
  94.  
  95. if step != 0:
  96. products[i] += step
  97. split_values[i] = round(products[i] / MULTIPLIER, precision)
  98. diff -= step
  99.  
  100. # 验证总和(必须正确)
  101. final_sum = sum(products)
  102. assert final_sum == TARGET_SUM, f"总和错误:{final_sum}≠{TARGET_SUM}"
  103.  
  104. # 统计结果
  105. value_counts = {v: split_values.count(v) for v in set(split_values)}
  106. duplicates = [v for v, c in value_counts.items() if c == 2]
  107. std_dev = round(statistics.stdev(split_values), 2)
  108.  
  109. # 输出(不排序)
  110. output = [
  111. "=== 拆分结果 ===",
  112. "状态: ✅ 有效(总和精确匹配目标)",
  113. f"重复情况: 共{len(duplicates)}个值各出现2次: {duplicates}",
  114. f"分散度(标准差): {std_dev}",
  115. f"总和验证: {final_sum} == {TARGET_SUM}",
  116. " + ".join([f"{v}×{MULTIPLIER}={p}" for v, p in zip(split_values, products)]) + f" = {final_sum}",
  117. f"拆分值(未排序): {split_values}"
  118. ]
  119.  
  120. return "\n".join(output)
  121.  
  122.  
  123. # 直接运行
  124. print(generate_exact_split())
  125.  
Success #stdin #stdout 0.06s 13108KB
stdin
Standard input is empty
stdout
=== 拆分结果 ===
状态: ✅ 有效(总和精确匹配目标)
重复情况: 共1个值各出现2次: [15.2]
分散度(标准差): 1.93
总和验证: 99462 == 99462
16.5×605=10000 + 15.2×605=9196 + 15.1×605=9136 + 16.5×605=10000 + 10.8×605=6534 + 16.5×605=10000 + 13.3×605=8046 + 16.5×605=10000 + 16.2×605=9801 + 15.2×605=9196 + 12.5×605=7553 = 99462
拆分值(未排序): [16.5, 15.2, 15.1, 16.5, 10.8, 16.5, 13.3, 16.5, 16.2, 15.2, 12.5]