import itertools
# --------------------------
# 配置参数 - 可根据需求修改
# --------------------------
CONFIG = {
# 基础系数列表
'base_coefficients': [36.5, 41.5, 59, 68.5, 74, 91.5] ,
# 目标值
'target':266160,
# 单个系数乘积的最大限制
'max_product': 129000,
# 最大变量数量(根据问题特点固定为3以提高速度)
'max_vars': 3,
# 目标值阈值(超过此值使用3变量)
'target_threshold': 259000,
# 减少波动范围以加快计算
'fluctuation_range': [i * 0.5 for i in range(-2, 3)], # ±1.0范围,步长0.5
# 限制解的数量以避免不必要计算
'max_solutions_per_combo': 20,
# 最终筛选的最佳解数量
'max_best_solutions': 4,
# 平衡解的数量
'balanced_solutions_count': 2
}
def find_solutions(config):
"""优化版:采用数学推导和剪枝策略加速求解"""
solutions = []
# 提取配置参数
target = config['target']
base_coefficients = config['base_coefficients']
max_product = config['max_product']
max_vars = config['max_vars']
target_threshold = config['target_threshold']
fluctuations = config['fluctuation_range']
max_solutions = config['max_solutions_per_combo']
# 根据目标值确定变量数量(直接使用3变量以加速)
num_vars = 3 if target > target_threshold else min(3, max_vars)
# 对系数排序,优先尝试大系数组合(减少迭代次数)
coefficients = sorted(base_coefficients, reverse=True)
# 只处理3变量情况,这是最可能找到解的组合且效率最高
# 生成系数组合(只取较大的系数,小系数组合可能性低)
start_idx = 0
end_idx = min(5, len(coefficients)) # 只取前5个较大的系数组合
for combo in itertools.combinations(coefficients[start_idx:end_idx], num_vars):
# 计算每个系数的可能值范围(使用更严格的范围)
ranges = []
valid = True
for coeff in combo:
if coeff <= 0:
valid = False
break
# 计算更精确的取值范围
min_val = max(1, int((target - (max_product * (num_vars - 1))) / coeff))
max_val = min(int(max_product / coeff), int(target / coeff))
if min_val > max_val:
valid = False
break
ranges.append(range(min_val, max_val + 1))
if not valid:
continue
# 优化搜索顺序:先处理中间变量,减少外层循环次数
# 对于3变量,固定前两个变量的范围,计算第三个变量
coeff1, coeff2, coeff3 = combo
range1, range2, range3 = ranges
# 限制第一个变量的范围,只取中间部分(加速)
step = max(1, len(range1) // 20) # 跳步采样,减少50倍计算量
for x in range1[::step]:
product1 = coeff1 * x
remaining1 = target - product1
if remaining1 <= 0:
continue
# 计算第二个变量的有效范围
min_y = max(range2.start, int((remaining1 - (coeff3 * range3.stop)) / coeff2))
max_y = min(range2.stop - 1, int((remaining1 - (coeff3 * range3.start)) / coeff2))
if min_y > max_y:
continue
# 对第二个变量也进行跳步采样
y_step = max(1, (max_y - min_y) // 20)
for y in range(min_y, max_y + 1, y_step):
product2 = coeff2 * y
remaining2 = remaining1 - product2
if remaining2 <= 0:
continue
# 直接计算第三个变量,无需循环
if remaining2 % coeff3 == 0:
z = int(remaining2 / coeff3)
if z in range3:
product3 = coeff3 * z
# 验证总和
if abs(product1
+ product2
+ product3
- target
) < 1e-6: solutions.append({
'coefficients': combo,
'values': (x, y, z),
'total': target,
'num_vars': num_vars,
'products': (product1, product2, product3)
})
# 找到足够解后提前退出
if len(solutions) >= max_solutions:
return solutions
# 如果没有找到解,再尝试系数波动(简化版)
if not solutions and len(fluctuations) > 0:
for combo in itertools.combinations(coefficients[:4], num_vars): # 只取前4个大系数
# 生成波动组合(减少波动数量)
fluctuated_combos = []
for i in range(num_vars):
if i == 0: # 只对第一个系数进行波动
fluctuated_combos.append([combo[i] + d for d in fluctuations])
else:
fluctuated_combos.append([combo[i]]) # 其他系数不波动
for fluctuated_combo in itertools.product(*fluctuated_combos):
if any(c <= 0 for c in fluctuated_combo):
continue
# 计算变量范围
ranges = []
valid = True
for coeff in fluctuated_combo:
min_val = max(1, int((target - (max_product * (num_vars - 1))) / coeff))
max_val = min(int(max_product / coeff), int(target / coeff))
if min_val > max_val:
valid = False
break
ranges.append(range(min_val, max_val + 1))
if not valid:
continue
# 同样的优化搜索方式
coeff1, coeff2, coeff3 = fluctuated_combo
range1, range2, range3 = ranges
step = max(1, len(range1) // 20)
for x in range1[::step]:
product1 = coeff1 * x
remaining1 = target - product1
if remaining1 <= 0:
continue
min_y = max(range2.start, int((remaining1 - (coeff3 * range3.stop)) / coeff2))
max_y = min(range2.stop - 1, int((remaining1 - (coeff3 * range3.start)) / coeff2))
if min_y > max_y:
continue
y_step = max(1, (max_y - min_y) // 20)
for y in range(min_y, max_y + 1, y_step):
product2 = coeff2 * y
remaining2 = remaining1 - product2
if remaining2 <= 0:
continue
z = remaining2 / coeff3
if abs(z
- round
(z
)) < 1e-6: z = int(round(z))
if z in range3:
product3 = coeff3 * z
if abs(product1
+ product2
+ product3
- target
) < 1e-6: solutions.append({
'coefficients': fluctuated_combo,
'values': (x, y, z),
'total': target,
'num_vars': num_vars,
'fluctuated': True,
'products': (product1, product2, product3)
})
if len(solutions) >= max_solutions:
return solutions
return solutions
def select_best_solutions(solutions, config):
"""简化版筛选函数,提高速度"""
if not solutions:
return []
# 提取配置参数
max_best = config['max_best_solutions']
balanced_count = config['balanced_solutions_count']
# 计算每个解的平衡分数(使用简化计算)
for sol in solutions:
# 使用乘积的方差作为平衡分数(值越小越平衡)
p1, p2, p3 = sol['products']
mean = (p1 + p2 + p3) / 3
sol
['balance_score'] = (abs(p1
- mean
) + abs(p2
- mean
) + abs(p3
- mean
)) / 3 # 改用绝对值和,更快
# 按平衡分数排序
solutions.sort(key=lambda x: x['balance_score'])
# 选择最佳解
result = []
# 先选平衡解
result.extend(solutions[:balanced_count])
# 再选普通解
result.extend(solutions[balanced_count:balanced_count + (max_best - balanced_count)])
return result[:max_best]
def main():
# 查找所有可能的解(优化版,速度更快)
all_solutions = find_solutions(CONFIG)
if not all_solutions:
print("未找到任何解")
return
# 选择最佳解
best_solutions = select_best_solutions(all_solutions, CONFIG)
# 处理解,将系数按从小到大排序
processed_solutions = []
for sol in best_solutions:
# 组合系数和值并排序
combined = list(zip(sol['coefficients'], sol['values'], sol['products']))
combined_sorted = sorted(combined, key=lambda x: x[0]) # 按系数排序
sorted_coeffs, sorted_values, sorted_products = zip(*combined_sorted)
processed_sol = sol.copy()
processed_sol['sorted_coefficients'] = sorted_coeffs
processed_sol['sorted_values'] = sorted_values
processed_sol['sorted_products'] = sorted_products
processed_sol['is_balanced'] = len(processed_solutions) < CONFIG['balanced_solutions_count']
processed_solutions.append(processed_sol)
# 按排序后的系数组合分组显示结果
combo_groups = {}
for sol in processed_solutions:
combo_key = sol['sorted_coefficients']
if combo_key not in combo_groups:
combo_groups[combo_key] = []
combo_groups[combo_key].append(sol)
# 显示每个组合及其解
for combo, solutions in combo_groups.items():
coeff_labels = [chr(97 + i) for i in range(len(combo))] # a, b, c...
combo_str = ", ".join([f"{label}={coeff:.1f}" for label, coeff in zip(coeff_labels, combo)])
print(f"组合: {combo_str} ({len(solutions)} 个有效解)")
for i, sol in enumerate(solutions, 1):
# 第一行:未知数
values_str = ", ".join([f"{chr(120 + j)}={val}" for j, val in enumerate(sol['sorted_values'])])
print(f" {i}. {values_str},")
# 第二行:乘积和总和
products_str = ", ".join([f"{label}*{chr(120 + j)}={p:.1f}"
for j, (label, p) in enumerate(zip(coeff_labels, sol['sorted_products']))])
balanced_tag = " [平衡解]" if sol['is_balanced'] else ""
print(f" {products_str}, 总和 = {sol['total']:.1f}{balanced_tag}")
print()
if __name__ == "__main__":
main()