如何反转二进制方程,以便我可以找到哪些输入将产生给定的输出。
示例:
Inputs: i0 through i8
Outputs: o0 through o8
Operators: ^ = XOR, & = AND
二元方程:
(1&i0) ^ (1&i1) ^ (0&i2) ^ (1&i3) ^ (0&i4) ^ (0&i5) ^ (0&i6) ^ (0&i7) ^ (0&i8) = o0
(0&i0) ^ (1&i1) ^ (0&i2) ^ (1&i3) ^ (1&i4) ^ (0&i5) ^ (0&i6) ^ (0&i7) ^ (0&i8) = o1
(0&i0) ^ (1&i1) ^ (1&i2) ^ (0&i3) ^ (0&i4) ^ (1&i5) ^ (0&i6) ^ (0&i7) ^ (0&i8) = o2
(1&i0) ^ (0&i1) ^ (0&i2) ^ (1&i3) ^ (0&i4) ^ (0&i5) ^ (0&i6) ^ (0&i7) ^ (0&i8) = o3
(0&i0) ^ (1&i1) ^ (0&i2) ^ (1&i3) ^ (1&i4) ^ (0&i5) ^ (0&i6) ^ (0&i7) ^ (0&i8) = o4
(0&i0) ^ (0&i1) ^ (0&i2) ^ (0&i3) ^ (0&i4) ^ (1&i5) ^ (0&i6) ^ (0&i7) ^ (0&i8) = o5
(0&i0) ^ (0&i1) ^ (0&i2) ^ (1&i3) ^ (0&i4) ^ (0&i5) ^ (1&i6) ^ (0&i7) ^ (0&i8) = o6
(0&i0) ^ (0&i1) ^ (0&i2) ^ (1&i3) ^ (1&i4) ^ (0&i5) ^ (1&i6) ^ (1&i7) ^ (0&i8) = o7
(0&i0) ^ (0&i1) ^ (0&i2) ^ (0&i3) ^ (0&i4) ^ (1&i5) ^ (0&i6) ^ (0&i7) ^ (1&i8) = o8
以矩阵形式:
1,1,0,1,0,0,0,0,0,1
0,1,0,1,1,0,0,0,0,1
0,1,1,0,0,1,0,0,0,1
1,0,0,1,0,0,0,0,0,1
0,1,0,1,1,0,0,0,0,1
0,0,0,0,0,1,0,0,0,1
0,0,0,1,0,0,1,0,0,1
0,0,0,1,1,0,1,1,0,1
0,0,0,0,0,1,0,0,1,1
其他限制:
如何通过算法查找输入i0 -i8,使输出o0-o8为1?我真正想要找到的是否有这样的解决方案。
我需要一种可扩展到大型网络的算法,至少可达100个输入/输出。
答案 0 :(得分:5)
使用XOR(而不是OR),乍一看似乎某种形式的Gauss–Jordan elimination至少可以简化问题。在缩减row echelon form上修改维基百科文章中的伪代码,我们得到:
function ToReducedRowEchelonForm(Matrix M) is
// 'lead' is the column index in a row of the leading 1
lead := 0
rowCount := the number of rows in M
columnCount := the number of columns in M
for 0 ≤ r < rowCount do
if columnCount ≤ lead then
stop
end if
i = r
// Find row with lead point
while M[i, lead] = 0 do
i = i + 1
if rowCount = i then
// no pivot in this column, move to next
i = r
lead = lead + 1
if columnCount = lead then
stop
end if
end if
end while
Swap rows i and r
for 0 ≤ i < rowCount do
if i ≠ r do
Set row i to row i XOR row r
end if
end for
lead = lead + 1
end for
end function
将样本转换为:
1,0,0,0,0,0,0,1,0,0
0,1,0,0,0,0,0,0,0,0
0,0,1,0,0,0,0,0,0,0
0,0,0,1,0,0,0,1,0,1
0,0,0,0,1,0,0,1,0,0
0,0,0,0,0,1,0,0,0,1
0,0,0,0,0,0,1,1,0,0
0,0,0,0,0,0,0,0,1,0
0,0,0,0,0,0,0,0,0,0
从那里,您可以调整integer partitioning算法来生成行的可能输入,并考虑以前行的分区。生成分区是备忘录的理想选择。
仍需要进行时序分析,看看上述情况是否值得。
答案 1 :(得分:4)
关于xor
的一个有趣的事情是:
a ^ b ^ b = a
这允许很好的操作,假设你有:
a ^ b = c
然后,您可以通过a
双方xor
轻松找出b
,获取:
a = c ^ b
如果我在你的位置,我会用这个技巧从输出中获取输入。方程中出现的and
仅具有从某些方程中移除某些输入变量的效果,因此对此方法没有任何问题。
首先,您必须知道,可能不是特定系数矩阵的解决方案,例如,如果输入永远不会出现在任何等式中(即,一列全0中的矩阵),或者如果一个方程出现两次(即两个相同的行),或者一个方程是另外两个方程的组合。
现在,假设您有的矩阵可以解决您的问题,那么该方法将使用每个等式来查找其中一个输入。对于每个等式,xor
除了一个输入之外的所有输入的两侧(并且每个等式的varry这个输入)。例如,假设我想使用第一个等式来查找i0
,第二个等式找到i1
(注意输入必须出现在等式中才能生成此值),我现在要:
i0 = o0 ^ i1 ^ i3
i1 = o1 ^ i3 ^ i4
继续其他方程,然后用方程中的值替换右侧的所有输入。递归重复,直到右侧只包含输出。如果重复所有方程,您将找到所有输入的值。
我肯定这种方法可以使用已经建立的方法在求解线性方程组时进行优化,特别是利用矩阵形式。
答案 2 :(得分:0)
您可以在多项式时间内解决2-SAT问题,请参阅here。
以下是带有快速算法的paper的链接(重数学我会继续寻找更好的链接)。
另一个与heavy math and pseudocode的链接。
编辑:虽然我发现了很多关于此的论文,但我没有看到太多可实施的代码。大多数工作都是为了证明可满足性。您可能必须简化子句(在每次运行时删除带有零的子句),然后使用递归算法来证明不可靠性,如果您发现它已经满意,那么您已经解决了它。