查找任何行的总和是不是等于具有 SUM、ANY、SIZE 的任何列的总和
Posted
技术标签:
【中文标题】查找任何行的总和是不是等于具有 SUM、ANY、SIZE 的任何列的总和【英文标题】:Find if sum of any row is equal to sum of any column with SUM, ANY, SIZE查找任何行的总和是否等于具有 SUM、ANY、SIZE 的任何列的总和 【发布时间】:2015-02-22 03:19:14 【问题描述】:导师给了我一个任务,检查二维矩阵中是否有任何行的总和等于任何列的总和。只允许使用 **1 loop**
和 sum
,any
,size
。
a = [2 3 4; 5 5 2; 1 3 3; 1 1 1]; --- % Just an example %
rows = size(a,1);
cols = size(a,2);
x = [rows, cols];
tA = a'; i = 1;
RowSum = zeros(rows,1)';
ColSum = zeros(1,cols);
while (i<=max(x))
if (size(a,1)>=i)
RowSum(i) = sum(a(i,:));
end
if (size(tA,1)>=i)
ColSum(i) = sum(tA(i,:));
end
i=i+1;
end
我知道这可能有点乱,但它给了我这份工作。现在我不知道如何检查RowSum
和ColSum
中是否有任何匹配值。 (不能使用intersect
);有什么想法吗?
【问题讨论】:
我认为你不应该问关于 SO 的作业问题。 @LordHenryWotton 我说“导师”是指我的朋友(我不是学生)。我刚到了不知道如何从这里继续进步的地步。 两个提示:您不需要循环来对列和行求和(请参阅sum
),您应该阅读any
文档以了解比较部分。
@TroyHaskin 我了解,我知道如何使用 sum(A,1)
表示列总和,使用 sum(A,2)
表示行总和。如果我的矩阵不是NxN
..,我不知道如何使用any
@DanielWatson any
也接受一个逻辑向量并产生一个逻辑标量(true
,如果有的话是true
;否则是false
)。因此,any
可以判断向量是否包含与标量匹配的元素:tf = any(v==s)
。
【参考方案1】:
解决方案及代码讨论
您可以采用此三步流程并通过 sum
、size
和 @987654325 实施解决方案@ 和 without using any loop
!!
这种实现要遵循的步骤可以分为三个步骤-
获取输入矩阵沿行和列的总和。
计算沿行总和的所有元素与沿列总和的距离矩阵。
本质上是这些步骤中最重要的一步,否则您至少需要一个循环或bsxfun
(用于内部复制)来执行此操作。
现在,这里的距离矩阵计算是用矩阵乘法进行的,是this solution to Speed-efficient classification in Matlab
的简化情况。
对于所有距离矩阵元素,查看是否有任何元素为零。
实现上述步骤的代码如下所示 -
%// Get the sum of rows and columns into column vectors - A and B respectively
A = sum(M,2)
B = sum(M,1)' %//'
%// Calculate the distance matrix between A and B
nA = size(A,1);
nB = size(B,1);
A_ext(nA,3) = 0;
A_ext(:,1) = 1;
A_ext(:,2) = -2*A;
A_ext(:,3) = A.^2;
B_ext(nB,3) = 0;
B_ext(:,3) = 1;
B_ext(:,1) = B.^2;
B_ext(:,2) = B;
distmat = A_ext * B_ext.'; %//'
%// For all distance matrix values check if any is zero for the final output
out = any(distmat(:)==0)
样品运行和验证
>> M (Sample input matrix)
M =
2 14 3
5 6 7
1 5 5
3 1 2
可以看出,沿第三行的和为11
,与沿第一列的和相同。因此,在距离矩阵中,至少有一个元素必须是zero
。
>> A (Sum along rows)
A =
19
18
11
6
>> B (Sum along columns)
B =
11
26
17
>> distmat (distance matrix between A and B)
distmat =
64 49 4
49 64 1
0 225 36
25 400 121
如前所述,(3,1)
处有一个零,因此any(distmat(:)==0)
的最终输出将是1
,这是预期的最终结果。
【讨论】:
超级!!伟大的想法:) 在尝试了解您的解决方案后,您能否解释一下距离矩阵的工作原理? (这些值代表什么,除了矩阵乘法)。 [你为什么要乘 -2*A?] @DanielWatson 解决方案中列出的链接应该可以清除这些问题。这里it is linked again。在Vectorized Variations
下,查找变量#1 并将dim
设置为1
。因此,您需要将此解决方案视为该链接解决方案的特例。【参考方案2】:
这就是我所做的:
ColSum = sum(a,1);
RowSum = sum(a,2)';
r = 0;
for i=1:length(ColSum)
if (any(RowSum==ColSum(i)))
r = 1;
end
end
disp(r);
现在正在考虑如何在没有循环的情况下处理它..
【讨论】:
有什么方法可以在没有循环且仅使用上述功能的情况下完成整个事情? 只有上面的函数没有循环?我倾向于不。 另外,您可以使用break
命令退出for
-loop,因为您只查找匹配项的存在而不是匹配项的总数。
@TroyHaskin 我的朋友说这是可能的:/ 当我有解决方案时,我会在这里发布..
@TroyHaskin 好吧,我几乎要放弃了,直到我想出了一种方法可以不用循环并使用这三个函数here。【参考方案3】:
在你用一个循环解决它之后,sum
,any
,size
,我建议你阅读bsxfun
并找到一个没有循环的单行解决方案bsxfun
,@987654327 @,any
(鼠标悬停查看):
any(any(bsxfun(@eq, sum(a,1), sum(a,2))))
【讨论】:
酷,谢谢。我想这不是我被允许使用的功能,因为我还没有了解它。不过很高兴知道! 我想出了一种方法来做bsxfun(@eq
,方法是计算距离矩阵并检查它的任何元素是否为零。所以,这对我来说很有趣。然后,我在这两者之间运行了一些基准测试,但没有看到基于距离矩阵的解决方案比 bsxfun(@eq
有任何改进,但我认为这是一个有趣的替代方案,也许只是为了好玩:)
@Divakar 所以你设法做到了没有循环,只有这三个功能!干得好!
@LuisMendo 是的!基本上,bsxfun(@eq
转换为 pdist2()==0
,您之前可能使用过。效率不高,但一个有趣的选择:)
@Divakar 是的,我想过pdist2
,但不允许这样做。现在我记得你以前用过矩阵乘法而不是pdist2
以上是关于查找任何行的总和是不是等于具有 SUM、ANY、SIZE 的任何列的总和的主要内容,如果未能解决你的问题,请参考以下文章