α=0.05,β=0.1,p1=0.015,p2=0.1
求解未知数 n 和 c!
乍一看,缺少一些关于您的应用程序如何定义可接受的解决方案的信息,但我将做出一些假设并提供一个(有点幼稚的)近似答案。
上下文第一:按原样提出的问题是一组 2 个未知数的 2 个代数方程,要在非负整数的 2D 网格上求解。我假设您的意思是未知数是非负整数,而不是,例如,来自问题公式的实数,涉及组合项。此外,请注意,每当 n 小于 c 时,求和最终将涉及对负数的阶乘运算,形式上未定义,因此我将进一步建议假设我们解决非负整数对的三角域,其中 n 大于或等于 c。
因此,要完善解决方案的定义,必须指定允许的数值容差(要求完全相等或从您的应用程序的角度来看允许一些错误)。除非从问题域中可以保证整数存在精确求解,否则我将继续假设具有已知误差的近似值是有意义/有价值的。最后:我将假设您正在寻找 A 解决方案(不是所有解决方案),并且我将限制搜索空间,正如您将在下面的简单脚本中看到的那样。
综上所述,我没有任何代数操作来暗示这会导致解决方案,并且我不知道可以在整数网格上解决此非线性问题的商业/开源求解器。令人惊讶的是,选择一个合理的网格并详尽地检查一些选项,会产生以下近似解:
Opt n: 52, opt c: 2, min_err (residual L2 norm): 0.0074985711238005955
这当然并不是说对于未访问的网格的某些部分不能有更准确的近似值。这样的保证,如果有的话,可以通过进一步的分析来实现,例如如果方程 wrt n 和 c 的右手边的单调行为等。
为了达到上面建议的简单近似值,我将您的右侧视为 n 和 c 的函数,并进行了一些详尽的评估,跟踪左侧所需值的误差。然后,误差由误差向量的 L2 范数定义 - 只是在当前位置评估的 RHS 与每个方程的 LHS 之间的差异。这是通过以下脚本完成的,当然对于较大的 n 和 c 值而言,该脚本是不可扩展的,而且据我所知,最近的候选者位于搜索空间的内部,这只是机会:
import math
import numpy as np
def eval_eq(n, c, p):
res = 0
for d in range(c + 1):
res += (math.factorial(n) / (math.factorial(d) * (math.factorial(n - d)))) * (p ** d) * ((1. - p) ** (n - d))
return res
def eval_err_norm(n, c):
p1 = 0.015
p2 = 0.1
beta = 0.1
alpha = 0.05
eq1_val = eval_eq(n, c, p1)
eq2_val = eval_eq(n, c, p2)
err1 = eq1_val - (1. - alpha)
err2 = eq2_val - beta
l2_err = np.linalg.norm(np.array([err1, err2]))
return l2_err
if __name__ == '__main__':
err = np.inf
opt_n = None
opt_c = None
for n_ in range(100):
for c_ in range(100):
if n_ < c_:
continue
else:
cur_err = eval_err_norm(n_, c_)
if cur_err < err:
err = cur_err
opt_n = n_
opt_c = c_
print(f'Opt n: {opt_n}, opt c: {opt_c}, min_err (residual L2 norm): {err}')