import itertools
CONFIG = {
# 基础系数列表
'base_coefficients': [38.5, 44, 61, 70.5, 75.5, 93],
# 目标值
'target': 268668,
# 单个系数乘积的最大限制
'max_product': 129000,
# 最大变量数量
'max_vars': 4,
# 目标值阈值(超过此值使用3-4变量)
'target_threshold': 259000,
# 系数波动范围(±1.0,步长0.1)
'fluctuation_range': [i * 0.1 for i in range(-10, 11)],
# 每个组合的最大解数量(用于提前终止)
'max_solutions_per_combo': 100,
# 最终筛选的最佳解数量(平衡解+普通解)
'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']
# 对系数排序,优先尝试大系数组合,减少迭代次数
coefficients = sorted(base_coefficients, reverse=True)
# 根据目标值确定变量数量范围
start_vars, end_vars = (3, 4) if target > target_threshold else (1, max_vars)
# 按变量数量递增搜索(优先少变量解)
for num_vars in range(start_vars, end_vars + 1):
# 生成不重复的系数组合
for combo in itertools.combinations(coefficients, num_vars):
# 计算每个系数的最大可能值
max_values = []
valid = True
for coeff in combo:
if coeff <= 0:
valid = False
break
# 单个系数乘积不超过最大限制
max_val = int(min(max_product / coeff, target / coeff)) + 1
if max_val <= 0:
valid = False
break
max_values.append(max_val)
if not valid:
continue
# 智能搜索策略:前n-1个变量遍历,最后一个变量反推
if num_vars == 1:
# 单变量情况
coeff = combo[0]
if target % coeff == 0:
val = int(target / coeff)
if 1 <= val <= max_values[0]:
solutions.append({
'coefficients': combo,
'values': (val,),
'total': target,
'num_vars': num_vars
})
else:
# 多变量情况
first_coeffs = combo[:-1]
last_coeff = combo[-1]
first_max_values = max_values[:-1]
last_max_val = max_values[-1]
# 生成前n-1个变量的所有组合
for first_values in itertools.product(*[range(1, mv+1) for mv in first_max_values]):
# 计算已用总和
used = sum(c * v for c, v in zip(first_coeffs, first_values))
remaining = target - used
if remaining <= 0:
continue
if remaining % last_coeff == 0:
last_val = int(remaining / last_coeff)
if 1 <= last_val <= last_max_val:
# 验证总乘积是否符合要求
products = [c * v for c, v in zip(first_coeffs, first_values)] + [last_coeff * last_val]
if all(p <= max_product for p in products):
values = first_values + (last_val,)
solutions.append({
'coefficients': combo,
'values': values,
'total': target,
'num_vars': num_vars
})
# 找到足够解后提前退出
if len(solutions) >= max_solutions:
break
if len(solutions) >= max_solutions:
break
# 如果没有找到解,尝试系数波动
if not solutions:
for num_vars in range(start_vars, end_vars + 1):
for combo in itertools.combinations(coefficients, num_vars):
# 生成所有可能的波动组合
fluctuated_coeffs_list = []
for coeff in combo:
fluctuated_coeffs_list.append([coeff + d for d in fluctuations])
# 尝试每个波动后的系数组合
for fluctuated_combo in itertools.product(*fluctuated_coeffs_list):
if any(c <= 0 for c in fluctuated_combo):
continue
# 计算每个系数的最大可能值
max_values = []
valid = True
for coeff in fluctuated_combo:
max_val = int(min(max_product / coeff, target / coeff)) + 1
if max_val <= 0:
valid = False
break
max_values.append(max_val)
if not valid:
continue
# 使用同样的智能搜索策略
if num_vars == 1:
coeff = fluctuated_combo[0]
if abs(target
% coeff
) < 1e-6: # 考虑浮点误差 val = int(round(target / coeff))
if 1 <= val
<= max_values
[0] and
abs(coeff
* val
- target
) < 1e-6: solutions.append({
'coefficients': fluctuated_combo,
'values': (val,),
'total': target,
'num_vars': num_vars,
'fluctuated': True
})
else:
first_coeffs = fluctuated_combo[:-1]
last_coeff = fluctuated_combo[-1]
first_max_values = max_values[:-1]
last_max_val = max_values[-1]
for first_values in itertools.product(*[range(1, mv+1) for mv in first_max_values]):
used = sum(c * v for c, v in zip(first_coeffs, first_values))
remaining = target - used
if remaining <= 0:
continue
# 处理浮点除法
last_val = remaining / last_coeff
if abs(last_val
- round
(last_val
)) < 1e-6: last_val = int(round(last_val))
if 1 <= last_val <= last_max_val:
# 验证总乘积和总和
products = [c * v for c, v in zip(first_coeffs, first_values)] + [last_coeff * last_val]
if all(p <= max_product for p in products):
total = sum(c * v for c, v in zip(fluctuated_combo, first_values + (last_val,)))
if abs(total
- target
) < 1e-6: values = first_values + (last_val,)
solutions.append({
'coefficients': fluctuated_combo,
'values': values,
'total': total,
'num_vars': num_vars,
'fluctuated': True
})
if len(solutions) >= max_solutions:
break
# 如果仍然没有找到解,取消最大乘积限制
if not solutions:
for num_vars in range(start_vars, end_vars + 1):
for combo in itertools.combinations(coefficients, num_vars):
# 不限制最大乘积,但设置合理范围
max_values = [int(target / coeff) + 100 for coeff in combo if coeff > 0]
if any(mv <= 0 for mv in max_values):
continue
# 使用相同的智能搜索策略
if num_vars == 1:
coeff = combo[0]
if target % coeff == 0:
val = int(target / coeff)
if val > 0:
solutions.append({
'coefficients': combo,
'values': (val,),
'total': target,
'num_vars': num_vars,
'unrestricted': True
})
else:
first_coeffs = combo[:-1]
last_coeff = combo[-1]
first_max_values = max_values[:-1]
last_max_val = max_values[-1]
for first_values in itertools.product(*[range(1, mv+1) for mv in first_max_values]):
used = sum(c * v for c, v in zip(first_coeffs, first_values))
remaining = target - used
if remaining <= 0:
continue
if remaining % last_coeff == 0:
last_val = int(remaining / last_coeff)
if 1 <= last_val <= last_max_val:
values = first_values + (last_val,)
solutions.append({
'coefficients': combo,
'values': values,
'total': target,
'num_vars': num_vars,
'unrestricted': True
})
if len(solutions) >= max_solutions:
break
return solutions
def select_best_solutions(solutions, config):
"""筛选最佳解,平衡解和普通解按配置参数设置"""
if not solutions:
return []
# 提取配置参数
max_best = config['max_best_solutions']
balanced_count = config['balanced_solutions_count']
# 按变量数量排序,优先选择变量少的解
solutions.sort(key=lambda x: x['num_vars'])
# 计算每个解的平衡分数(各乘积的标准差)
for sol in solutions:
products = [c * v for c, v in zip(sol['coefficients'], sol['values'])]
mean = sum(products) / len(products)
std = (sum((p - mean) **2 for p in products) / len(products))** 0.5
sol['balance_score'] = std
# 先按变量数量分组
var_groups = {}
for sol in solutions:
key = sol['num_vars']
if key not in var_groups:
var_groups[key] = []
var_groups[key].append(sol)
# 优先从变量最少的组中选择解
result = []
balanced_selected = 0
others_selected = 0
# 按变量数量升序处理各组
for var_count in sorted(var_groups.keys()):
group = sorted(var_groups[var_count], key=lambda x: x['balance_score'])
# 先选平衡解
for sol in group:
if balanced_selected < balanced_count:
sol['is_balanced'] = True
result.append(sol)
balanced_selected += 1
else:
break
# 再选普通解
needed_others = max_best - balanced_count
for sol in group[balanced_selected:]:
if others_selected < needed_others:
sol['is_balanced'] = False
result.append(sol)
others_selected += 1
else:
break
# 选够指定数量的解则停止
if len(result) >= max_best:
break
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)
# 按系数组合分组显示结果
combo_groups = {}
for sol in best_solutions:
# 使用系数元组作为键,确保相同组合分到一组
combo_key = tuple(sol['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():
# 生成系数字母标签 (a, b, c, d...)
coeff_labels = [chr(97 + i) for i in range(len(combo))]
# 构建组合字符串 (如 "a=41.5, b=59")
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):
# 构建未知数字符串 (如 "x=3070, y=2179")
values_str = ", ".join([f"{chr(120 + j)}={val}" for j, val in enumerate(sol['values'])])
# 构建乘积字符串 (如 "a*x=127405.0, b*y=128561.0")
products = [c * v for c, v in zip(sol['coefficients'], sol['values'])]
products_str = ", ".join([f"{label}*{chr(120 + j)}={p:.1f}"
for j, (label, p) in enumerate(zip(coeff_labels, products))])
# 构建平衡解标记
balanced_tag = " [平衡解]" if sol['is_balanced'] else ""
# 显示解信息
print(f" {i}. {values_str}, {products_str}, 总和={sol['total']:.1f}{balanced_tag}")
print() # 组合之间空一行
if __name__ == "__main__":
main()