如何用Python求解含Σ的方程,确定求和上限整数k
求解含求和方程中的整数k问题
问题描述
已知方程形式为 $\sum_{k=1}^N \left[ x + (k-1)(x - x_{\text{min}}) \right]^3 = C$,其中:
- $C$ 为已知常数(示例值为742.231)
- $x_{\text{min}}$ 为x的已知下限(示例值为3.652)
- $x$ 满足区间约束 $x_{\text{min}} \leq x < x_{\text{max}}$($x_{\text{max}}$ 已知)
- 需要求解求和的整数上限 $N$,预估 $N < 2000000$
是否可解?
可以求解。核心思路是先将求和式化简为闭合代数形式,消除求和符号,再结合x的区间约束,通过数值方法筛选出满足条件的整数N。
实现步骤
1. 化简求和式
先对求和项做变量替换:令 $d = x - x_{\text{min}}$(则 $d \geq 0$ 且 $d < x_{\text{max}} - x_{\text{min}}$),求和项可改写为:
$$\left[ x_{\text{min}} + kd \right]^3$$
利用立方和的展开公式与已知的整数幂求和公式,将求和式转化为关于N和x的闭合表达式:
$$
\sum_{k=1}^N (a + bk)^3 = N a^3 + 3a^2 b \cdot \frac{N(N+1)}{2} + 3a b^2 \cdot \frac{N(N+1)(2N+1)}{6} + b^3 \cdot \left( \frac{N(N+1)}{2} \right)^2
$$
其中 $a = x_{\text{min}}$,$b = d$。该闭合形式避免了直接遍历求和的性能损耗,尤其适合N接近2e6的场景。
2. 转化为约束验证问题
原方程变为 $S(N, x) = C$($S(N,x)$ 为化简后的闭合表达式)。我们可以:
- 先通过x的边界值快速缩小N的候选范围:当x=x_min时,求和结果为 $N \cdot x_{\text{min}}^3$;当x=x_max时,求和结果为对应最大值,由此确定N的大致遍历区间。
- 对每个候选N,判断是否存在x∈[x_min, x_max)使得 $S(N,x)=C$:若函数 $S(N,x)-C$ 在区间两端点的符号相反,则说明区间内存在解,再用数值方法求解x并验证。
3. 数值求解与验证
使用二分法求解每个N对应的x值,验证是否落在指定区间内,找到第一个符合条件的N即可停止计算。
代码实现示例
import numpy as np from scipy.optimize import root_scalar # 已知参数 known_value = 742.231 x_min = 3.652 x_max = 5.0 # 替换为实际的x上限 def sum_closed_form(N, x): d = x - x_min a = x_min b = d # 计算整数幂求和结果 sum_k = N * (N + 1) / 2 sum_k2 = N * (N + 1) * (2 * N + 1) / 6 sum_k3 = (N * (N + 1) / 2) ** 2 # 代入闭合公式 return N * a**3 + 3 * a**2 * b * sum_k + 3 * a * b**2 * sum_k2 + b**3 * sum_k3 def equation_for_x(x, N): return sum_closed_form(N, x) - known_value # 确定N的初始遍历范围 N_low = 1 N_high = int(known_value / (x_min**3)) + 2 # 扩大范围避免边界遗漏 found_N = None found_x = None for N in range(N_low, N_high + 1): # 计算区间端点的函数值 val_at_xmin = N * x_min**3 - known_value if val_at_xmin >= 0: # x=x_min时求和已达标,x增大后求和会更大,无符合条件的x continue val_at_xmax = sum_closed_form(N, x_max) - known_value if val_at_xmax <= 0: # x=x_max时求和仍未达标,区间内无满足条件的x continue # 区间内存在解,用二分法求解x sol = root_scalar(equation_for_x, args=(N,), bracket=[x_min, x_max], method='bisect') if sol.converged: found_N = N found_x = sol.root break if found_N: print(f"找到符合条件的整数k上限:{found_N},对应x值:{found_x:.6f}") else: print("未找到符合条件的整数k上限")
关键优化点
- 闭合形式化简将O(N)的求和操作降为O(1),大幅提升计算效率。
- 先通过边界值过滤无效N,减少不必要的计算。
- 二分法求解x保证了数值稳定性和准确性。
内容的提问来源于stack exchange,提问作者Ali_Sh
相关产品推荐
相关产品推荐

