我必须编写一个名为saddle
的函数,它在输入矩阵M中找到鞍点。对于这个问题,鞍点被定义为一个元素,其值大于或等于其行中的每个元素,并且小于或等于其列中的每个元素。该函数应返回一个名为indices
的矩阵,该矩阵恰好有两列。 indices
的每一行对应于一个鞍点,该行的第一个元素包含鞍点的行索引,第二列包含列索引。根据列主要顺序,在索引中提供鞍点,它们位于M中的顺序相同。如果M中没有鞍点,则indices是空数组。这是我到目前为止所拥有的:
% function indices = saddle(M)
% Definition of a test matrix M:
M = [0.8147 0.1270 0.6324 0.2785; ...
0.9058 0.9134 0.0975 0.5469];
[ rows,cols ] = size(M);
[valR,posR] = max(M,[],2);
[valC,posC] = min(M,[],1);
indices= [];
for i = 1:length(posR)
for j = 1:length(posC)
if posR(i) == posC(posR(i))
indices= [indices; posR(i),posC(i)];
end
end
end
当我对代码发表评论时,我已经定义了一个在位置(1,1)
上有一个鞍点的测试矩阵,但代码无法正常工作,因为它返回
indices =
1 1
1 1
1 1
1 1
我做错了什么?
答案 0 :(得分:1)
您只需要一个循环,而不是双循环。所有马鞍点候选人都是索引为(i, posR(i))
的条目。如果这个条目在其列中也是最小的,则表示i == posC(posR(i))
。
您还输出错误的数字:应为(i, posR(i))
。
for i = 1:length(posR)
if i == posC(posR(i))
indices= [indices; i, posR(i)];
end
end
请注意,您的算法忽略了某些条目可能相同的事实:函数max
和min
仅为您提供第一个最大或最小条目。对于浮点数,这可能是可以忽略的,但对于整数,这可能非常重要。
这是一种没有for循环并且考虑到可能的平等的方法:
saddles = (kron(valR,ones(1,cols))==M).*(kron(ones(rows,1),valC)==M);
[I, J] = find(saddles);
右边的两个因子中的每一个都是0-1矩阵,其中1s标记了马鞍的候选者。逐项乘积产生0-1矩阵,其中1s标记鞍点。然后find
命令返回鞍座的索引。
例如,使用测试示例M = [1 2 1 2 ; 5 3 4 3]
saddles =
0 1 0 1
0 0 0 0
I =
1
1
J =
2
4