【问题标题】:Getting full coordinates of the argmax of an array in Matlab在 Matlab 中获取数组的 argmax 的完整坐标
【发布时间】:2014-06-18 07:45:16
【问题描述】:

我有一个多维最大化问题。有(假设)一个状态和两个控制变量(分别为x1x2,x3):对于状态变量x1 的每个值,我们通过改变x2 和@ 来最大化一些目标函数987654326@.

那么,在 Matlab 中,我有一个 3 维数组,我们称它为 F,第一维是 x1,后一维是 (x2,x3)。

获得最大值很容易——只需设置: F_star=max(max(F,[],2),[],3); 这将返回每个 x1 的长度为 N_1 的最大值向量。

我的问题是获取最大化器的索引/坐标。

我的第一个猜测是使用扩展函数调用:

[F_star, maximizers]=max(max(F,[],2),[],3);

但是,这只对 OUTERMOST max 函数起作用,因此只会返回第 3 维中的最大化索引。

当然,你可以重复这个并改变尺寸:

[F_star, maximizers_3]=max(max(F,[],2),[],3);

[F_star, maximizers_2]=max(max(F,[],3),[],2);

但是两次取最大值似乎几乎没有效率(这对我的实际问题很重要,因为实际上有 3 个控制变量和 7 个状态变量,所以搜索我的整个数组是一个相当大的负担)。

对于提取所有坐标或索引的更简单方法有什么想法吗?

具体来说,这里有一个简单的例子:

F = 10*rand(2,2,2)

[y, z3] = max(max(F,[],2),[],3)

[y, z2] = max(max(F,[],3),[],2)

F(:,:,1) =

    2.1203    9.1380

    0.7735    7.0672


F(:,:,2) =

    5.5779    1.6620

    3.1343    6.2250


y =

    9.1380

    7.0672


z3 =

     1

     1


y =

    9.1380

    7.0672


z2 =

     2

     2

通过结合z2z3,我们得到了我们想要的: x1(即F(1,:,:))的第一个值时的最大值为9.1,发生在(z2(1),z3(1)) -- F(1,z2(1),z3(1))=F(1,2,1)

x2 的第一个值(即F(2,:,:))的最大值为 7.1,这发生在 (z2(2),z3(2)) -- F(1,z2(2),z3(2))=F(2,2,1)

有这样的东西会很棒: [F_star, z2, z3] = max(F,[2 3])

【问题讨论】:

    标签: arrays matlab optimization indexing


    【解决方案1】:

    “线性化”(结合)第二和第三维度与reshape;获得沿组合维度的最大化器的线性索引;并使用ind2sub 转换为两个子索引:

    [F_star ind] = max(reshape(F, size(F,1), []), [], 2);
    [z2 z3] = ind2sub([size(F,2) size(F,3)], ind);
    

    这将为您提供每个第一维切片的最大值 (F_star) 及其在第二维和第三维中的位置(z2z3)。


    对于三个以上的维度,如果要对每个第一维切片进行最大化,泛化很简单:

    s = size(F);
    [F_star ind] = max(reshape(F, s(1), []), [], 2);
    z = cell(1,numel(s)-1);
    [z{:}] = ind2sub(s(2:end), ind);
    

    位置在单元格数组z 中给出,这样z{1} 是你的z2z{2} 是你的z3 等等。

    【讨论】:

    • 我在想一些类似的事情!如果事实证明我通过删除其他 7 个维度过于简化了,我会跟进。谢谢。
    • @MichaelChirico 查看已编辑的答案(最后一部分)以获取任意数量的维度
    • 扩展比这更棘手——我有 7 个状态维度(不是简单示例中的 1 个)和 3 个选择维度。所以这概括为: s = size(F); [F_star ind] = max(reshape(F, [s(1:n) []]), [], 2); z = 单元格(1,numel(s)-n); [z{:}] = ind2sub(s((n+1):end), ind);其中 n 是状态维数。谢谢!
    • 实际上语法 [s(1:n) []] 似乎不起作用。而是: [s(1:n) prod(s((n+1):end))]
    • @MichaelChirico 这是真的。 reshape 中的 [] 可以与列表一起使用:reshape(F, s(1), s(2), s(3), [])。但不能使用矢量:reshape(F, s(1:n), []) 是不允许的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多