让我们假设我们有一个简单的矩阵3rows x 7cols。 矩阵仅包括零(0)和(1),如:
1 0 1 1 1 0 0
0 0 1 1 0 0 0
0 0 1 0 1 1 0
塞纳里奥: 如果我们知道每行中非零的总和,
(第一行是4,第二行是2,第三行是3.)(蓝线)
另外,如果我们知道每个col的总和(1,0,3,2,2,1,0)(绿线)
如果我们知道每个对角线的总和,从左上角到右下角(1,0,1,2,3,0,1,1,0)(红线)逆时针
最后我们知道从左下角到右上角(0,0,2,1,3,2,1,0,0)(黄线)的每个对角线的总和
我的问题是: 将这些值作为输入(以及矩阵3x7的长度),
4, 2, 3
1, 0, 3, 2, 2, 1, 0
1, 0, 1, 2, 3, 0, 1, 1, 0
0, 0, 2, 1, 3, 2, 1, 0, 0
我们如何绘制第一个矩阵? 经过深思熟虑后,我得出的结论是,这是一个具有3x7未知值和一些方程的线性方程组。 正确?
如何用C或其他方法制作算法来解决这些方程式? 我应该使用类似高斯方程的方法吗?
非常感谢任何帮助!
答案 0 :(得分:2)
从第一列开始。您知道顶部和底部值(来自红色和黄色列表的第一个值)。从绿色列表中的第一个中减去这两个的总和,现在你也有中间值。
现在正好向右走。
从红色列表中的下一个值中减去第一列的中间值,并获得第二列的最高值。从黄色列表中的下一个值中减去相同的中间值,并且您具有第二列的最低值。从绿色列表中的下一个值中减去这两个的总和,现在您有第二列的中间值。
等等
如果您要对其进行编码,您可以看到前两列是特殊情况,这将使代码变得丑陋。我建议在左侧使用两个全部为零的“ghost”列,以便您可以使用单一方法确定每列的顶部,底部和中间值。
这也很容易推广。你只需要使用(#rows)-1 ghost列。
享受。
答案 1 :(得分:2)
您可以使用奇异值分解来计算矩阵形式的线性齐次(和非齐次)方程组的非零最小二乘解。
如需快速浏览,请参阅:
http://campar.in.tum.de/twiki/pub/Chair/TeachingWs05ComputerVision/3DCV_svd_000.pdf
您应该首先将您的系统写成Ax = b形式的矩阵方程,其中x是21个未知数作为列向量,A是28 x 21矩阵,当乘出时形成线性系统。您基本上需要计算线性方程的矩阵A,计算A的奇异值分解并将结果插入方程式中,如公式9.17所示
有很多库会在C中为你计算SVD,所以你只需要制定矩阵并在9.17中执行计算。最困难的部分可能是了解它是如何工作的,使用库SVD函数需要相对较少的代码。
为了让您开始研究如何形成线性系统的方程式,请考虑一个简单的3 x 3情况。
假设我们的系统是
形式的矩阵1 0 1
0 1 0
1 0 1
我们对线性系统有以下输入:
2 1 2 (sum of rows - row)
2 1 2 (sum of colums - col)
1 0 3 0 1 (sum of first diagonal sets - t2b)
1 0 3 0 1 (sum of second diagonal sets - b2t)
所以我们现在为线性系统创建一个矩阵
A a1 a2 a3 b1 b2 b3 c1 c2 c3 unknowns (x) = result (b)
sum of row 1 [ 1 1 1 0 0 0 0 0 0 ] [a1] [2]
sum of row 2 [ 0 0 0 1 1 1 0 0 0 ] [a2] [1]
sum of row 3 [ 0 0 0 0 0 0 1 1 1 ] [a3] [2]
sum of col 1 [ 1 0 0 1 0 0 1 0 0 ] [b1] [2]
sum of col 2 [ 0 1 0 0 1 0 0 1 0 ] [b2] [1]
sum of col 3 [ 0 0 1 0 0 1 0 0 1 ] [b3] [2]
sum of t2b 1 [ 1 0 0 0 0 0 0 0 0 ] [c1] [1]
sum of t2b 2 [ 0 1 0 1 0 0 0 0 0 ] [c2] [0]
sum or t2b 3 [ 0 0 1 0 1 0 1 0 0 ] [c3] [3]
sum of t2b 4 [ 0 0 0 0 0 1 0 1 0 ] [0]
sum of t2b 5 [ 0 0 0 0 0 0 0 0 1 ] [1]
sum of b2t 1 [ 0 0 0 0 0 0 1 0 0 ] [1]
sum of b2t 2 [ 0 0 0 1 0 0 0 1 0 ] [0]
sum of b2t 3 [ 1 0 0 0 1 0 0 0 1 ] [3]
sum of b2t 4 [ 0 1 0 0 0 1 0 0 0 ] [0]
sum of b2t 5 [ 0 0 1 0 0 0 0 0 0 ] [1]
当你乘以Ax时,你会看到你得到了线性方程组。例如,如果将第一行乘以未知列,则得到
a1 + a2 + a3 = 2
你所要做的就是在等式中出现的任何列中加1,在其他地方加0。
现在你所要做的就是计算A的SVD并将结果插入公式9.17以计算未知数。
我推荐SVD,因为它可以有效地计算。如果您愿意,可以使用结果向量b(A | b)扩充矩阵A,并将A放在缩小的行梯形表格中以获得结果。
答案 2 :(得分:1)
对于一个10x15的1和0的数组,你会试图找到150个未知数并且有10 + 15 + 2 *(10 + 15-1)= 73个等式,如果你忽略了这些值被限制为任何一个或零。显然,你不能在此基础上创建一个具有独特解决方案的线性系统。
这个约束足以提供独特的解决方案吗?
对于具有以下总和的4x4矩阵,有两种解决方案:
- 1 1 1 1
| 1 1 1 1
\ 0 1 1 0 1 1 0
/ 0 1 1 0 1 1 0
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0
所以我不希望有更大的矩阵有一个独特的解决方案 - 许多地方都存在相同的对称性:
- 1 1 0 0 1 1
| 1 1 0 0 1 1
\ 0 1 0 0 1 0 1 0 0 1 0
/ 0 1 0 0 1 0 1 0 0 1 0
0 0 0 0 1 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 1
0 1 0 0 0 0
0 1 0 0 0 0
0 0 0 0 0 1
0 0 0 0 0 0
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 1 0
答案 3 :(得分:0)
这是另一种变化
Count the amount of unknown squares each sum passes through
While there are unsolved cells
Solve all the cells which are passed through by a sum with only one unknown square
Cells are solved by simply subtracting off all the known cells from the sum
Update the amount of unknown squares each sum passes through
没有边界情况,但与之前的答案非常相似。这将首先解决所有角落,然后是那些与角落相邻的角落,然后是那个距离更远的那一步,等等...
编辑:也将任何总和为零的路径归零,这应解决任何可解决的路径(我认为)