【问题标题】:Changing indices and order in arrays更改数组中的索引和顺序
【发布时间】:2013-05-24 14:33:04
【问题描述】:

我有一个结构mpc,其结构如下:

          num  type    col3    col4 ...
mpc.bus =   1     2     ...    ...
            2     2     ...    ...
            3     1     ...    ...
            4     3     ...    ...
            5     1     ...    ...
           10     2     ...    ...
           99     1     ...    ...

             to from   col3   col4 ...
mpc.branch =  1    2    ...    ...
              1    3    ...    ...
              2    4    ...    ... 
             10    5    ...    ...
             10   99    ...    ...

我需要做的是: 1:对mpc.bus的行重新排序,使得1类型的所有行都排在第一位,然后是2,最后是33 类型只有一个元素,没有其他类型(4 / 5 等)。

2:进行编号(mpc.bus 的第 1 列,连续,从 1 开始。

3:更改mpc.branch的to-from列中的数字,以对应mpc.bus中的新编号。

4:运行模拟后,将上述步骤颠倒,以与上述相同的顺序和编号出现。

使用find 更新mpc.bus 很容易。

type_1 = find(mpc.bus(:,2) == 1);
type_2 = find(mpc.bus(:,2) == 2);
type_3 = find(mpc.bus(:,2) == 3);

mpc.bus(:,:) = mpc.bus([type1; type2; type3],:);
mpc.bus(:,1) = 1:nb   % Where nb is the number of rows of mpc.bus

mpc.branch 中 to/from 列中的数字对应于 mpc.bus 中第 1 列中的数字。

也可以更新mpc.branchtofrom 列上的数字。

但是,我无法找到一种简单的方式来追溯我的脚步。我可以使用一些简单的命令来更新编号吗?

郑重声明:我故意不包含用于重新编号 mpc.branch 的代码,因为我确信有人有更智能、更简单的解决方案(这将使模拟完成后更容易重做)。

编辑:创建普通数组可能更容易(避免使用结构):

bus = mpc.bus;
branch = mpc.branch;

编辑#2:事情的顺序:

  1. 重新排序和重新编号。

  2. busbranch 的列 (3:end) 已更改。 (不是这个问题的一部分)

  3. 恢复原始顺序和索引。

谢谢!

【问题讨论】:

    标签: arrays matlab struct indexing


    【解决方案1】:

    我提出了这个解决方案。它生成一个n x 2矩阵,其中n对应mpc.bus中的行数和mpc.branch的临时副本:

    function [mpc_1, mpc_2, mpc_3] = minimal_example
    
    mpc.bus = [ 1     2;...
                2     2;...
                3     1;...
                4     3;...
                5     1;...
               10     2;...
               99     1];
    
    mpc.branch = [ 1    2;...
                   1    3;...
                   2    4;...
                  10    5;...
                  10   99];
    
    mpc.bus = sortrows(mpc.bus,2);
    
    mpc_1 = mpc;
    
    mpc_tmp = mpc.branch;
    
    for I=1:size(mpc.bus,1)
        PAIRS(I,1) = I;
        PAIRS(I,2) = mpc.bus(I,1);
        mpc.branch(mpc_tmp(:,1:2)==mpc.bus(I,1)) = I;
        mpc.bus(I,1) = I;
    end
    
    mpc_2 = mpc;
    % (a) the following mpc_tmp is only needed if you want to truly reverse the operation
    mpc_tmp = mpc.branch; 
    
    %
    % do some stuff
    %
    
    for I=1:size(mpc.bus,1)
        % (b) you can decide not to use the following line, then comment the line below (a)
        mpc.branch(mpc_tmp(:,1:2)==mpc.bus(I,1)) = PAIRS(I,2);
        mpc.bus(I,1) = PAIRS(I,2);
    end
    
    % uncomment the following line, if you commented (a) and (b) above:
    % mpc.branch = mpc_tmp;
    
    mpc.bus = sortrows(mpc.bus,1);
    
    mpc_3 = mpc;
    

    上面的最小示例可以按原样执行。三个输出(mpc_1mpc_2mpc_3)只是为了演示代码的工作原理,但在其他方面没有必要。

    1.) mpc.bus 使用sortrows 排序,简化了方法,而不是使用find 三次。它以mpc.bus 的第二列为目标,并对剩余的矩阵进行相应的排序。
    2.) 存储mpc.branch的原始内容。
    3.) 使用循环将mpc.bus 的第一列中的条目替换为升序数字,同时在mpc.branch 中相应地替换它们。在这里,mpc_tmp 的引用是必要的,因此请确保正确替换元素。
    4.) 之后,mpc.branch 可以与 (3.) 类似地恢复 - 在这里,有人可能会争辩说,如果原始的 mpc.branch 是早先存储的,则可以只复制矩阵。此外,mpc.bus 的原始值被重新分配。
    5.) 现在,sortrows 再次应用于mpc.bus,这次以第一列作为参考以恢复原始格式。

    【讨论】:

    • 谢谢!我认为这会奏效!我使用find 而不是sortrows 的原因是因为我实际上是在安排它:2 1 3 而不是1 2 3(虽然这部分很容易修复)。我希望避免循环,但我想在这种情况下会很难。再次感谢,我绝对可以使用这个 =) (如果有人有一个聪明的“快速修复”,我会将问题保持更长时间。如果没有,我明天会接受你的回答 =))
    • @Jack :如果想出一个少循环/无循环的想法,我会编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多