我试图用 28 个变量求解这个方程:
y = (a1 * x1) + (a2 * x2) + .... + (a28 * x28)
1) y 是已知的,a1、a2 一直到 a28 也是已知的。
2) x1, x2 ..... x28 是未知变量,它们在 [-4, 4] 范围内,增量为 0.1。
有人能解释一下我困惑的大脑,什么算法在这里使用最有效吗?
这等效于整数线性规划,尽管由于只有一个具有 28 个简单约束(边界,而不是方程组)的方程,您可能会做得更好。一般来说,这将是 NP 难的(请参阅https://en.wikipedia.org/wiki/Linear_programming#Integer_unknowns),但您可能可以使用几种实现(例如,请参阅如何选择整数线性编程求解器?)
您可以在 prolog 中对其进行编程(SICStus prolog 引擎,例如 Eclipse 上的 SPIDER IDE)。这个问题是状态空间搜索问题。并使用 clpfd 库(有限域上的约束逻辑编程)。然后你只做一个约束,X1 到 X28 将是域变量并给定约束 y #= a1*X1 + ... + a28*X28。优化状态空间搜索的方法也很少。
/edit:或者你可以尝试用任何命令式语言来做。还使用一些启发式方法 - 例如,选择一些执行点,您可以在其中检查当前结果(例如,您有一些 tmp.sum 并且您已经从 28 个值中计算了 15 个。如果 y 减去 temp sum 小于 MIN_VARIABLE_VALUE * i,其中 i 是索引,x_i 属于剩余变量,你可以放心地决定,你不会继续,bcs。你不能得到平等)。这个启发式首先出现在我的脑海中。在此使用也可以使用一些替换。但是应该对一些测试数据进行“研究”它的效率如何。
首先,将所有内容乘以 10,这样您就可以继续进行整数数学运算。同样在两边加上 sum(40*a_u) 会将 x_i 的范围更改为 [0,80]
其次,答案可能呈指数级,因此您的算法必须花费指数级时间。
鉴于有 80^28(大约 2^177)个可能的答案 - 这通常是不可能的。
现在如果 x_i 的范围是 [0,1](而不是 [0,80])并且我们添加一个等于 y 的额外项(并将 y 更改为 0),那么问题就变成了找到集合的子集加起来为零的整数。这是一个众所周知的 NP 完全问题,它似乎比你的更容易(尽管我没有明确的减少)。
可能有动态编程解决方案,但可能太慢了:
set<float> X;
X.insert(0)
for i = 1 to 28
for f = -4.0 to 4.0 step 0.1
for x in X
X.insert(x + a_i * f)
for x in X
if (x == y)
return true;
return false;
您可以通过传回可行范围([y + a_i*(-4.0), y + a_i*4.0])并在这些范围之外修剪不可行的部分解决方案来做得更好。