方程求解的置换

时间:2016-12-16 22:25:23

标签: combinatorics

如果存在等式3a + 6b +7d = 55并且解集是{1,4,6}但是未知解决方案中的哪个数字对应于哪个变量,是否有办法确定哪个数字与哪个变量对应没有使用蛮力?如果方程有1000个变量,这种方法可以扩展吗?谢谢!

1 个答案:

答案 0 :(得分:0)

这是一种强力解决方案,可以在无法找到解决方案的情况下进行修剪搜索。

让我们展示两件事。首先,如果系数和解是非负数,并且如果它们被表示为排序列表,那么最大值方程可以具有“并行和”,并且最小值是“反向和”#39; ;。

max = sum(c*s for c, s in zip(coeffs, sols))
min = sum(c*s for c, s in zip(coeffs, reversed(sols)))

足以看到四个数字0 <= a1 <= a20 <= b1 <= b2成立:

a1*b1 + a2*b2 = a1*b2 + a2*b1 + (a2-a1)*(b2-b1) >= a1*b2 + a2*b1.

其次,总是可以将问题转化为具有非负系数和解决方案的相同类型的问题。要移动&#39;非负的解决方案需要添加到所有解决方案的值-min(solutions)和结果-min(solutions)*sum(coefficients)。 类似的程序&#39;移动&#39;系数为非负数。

这是解决方案的python实现:

def C(coeffs, res, sols):
    _max = sum(i*j for i, j in zip(coeffs, sols))
    if _max < res:   # No result
        return None
    if _max == res:  # Result mapping coeffs <-> sols
        return sols
    _min = sum(i*j for i, j in zip(coeffs, reversed(sols)))
    if _min > res:   # No result
        return None
    if _min == res:  # Result mapping coeffs <-> reversed sols
        return sols[::-1]  # reverse sols
    # For next coefficient try all solutions
    for i, s in enumerate(sols):
        r = C(coeffs[1:], res - coeffs[0]*s, sols[:i] + sols[(i+1):])
        if r is not None:
            return [s] + r

print C([3, 6, 7], 55, [1, 4, 6])