【问题标题】:if-statement: how to rewrite in matlabif语句:如何在matlab中重写
【发布时间】:2016-08-28 09:28:47
【问题描述】:

我是 Matlab 的新手。我采用了复杂的if-statement 条件的工作代码,需要重写它。此代码应准备一些初始数据来解决优化任务。这个if-statement 条件看起来像:

x=[784.8 959.2 468 572 279 341 139.5 170.5 76.5 93.5 45 55];
a=nchoosek(x,6); % all possible combinations from 6 elements of x
n=length(a);
q=[];

 for i=1:n

if( ((a(i,1)==x(1)) & (a(i,2)==x(2))) | 
    ((a(i,1)==x(3)) & (a(i,2)==x(4))) | 
    ((a(i,1)==x(5)) & (a(i,2)==x(6))) |  
    ((a(i,1)==x(7)) & (a(i,2)==x(8))) |
    ((a(i,2)==x(3)) & (a(i,3)==x(4))) |  
    ((a(i,2)==x(5)) & (a(i,3)==x(6))) | 
    ((a(i,2)==x(7)) & (a(i,3)==x(8))) |  
    ((a(i,3)==x(3)) & (a(i,4)==x(4))) |  
    ((a(i,3)==x(5)) & (a(i,4)==x(6))) |  
    ((a(i,3)==x(7)) & (a(i,4)==x(8))) |  
    ((a(i,3)==x(9)) & (a(i,4)==x(10)))|  
    ((a(i,4)==x(5)) & (a(i,5)==x(6))) |  
    ((a(i,4)==x(7)) & (a(i,5)==x(8))) |  
    ((a(i,4)==x(9)) & (a(i,5)==x(10)))|  
    ((a(i,5)==x(5)) & (a(i,6)==x(6))) |  
    ((a(i,5)==x(7)) & (a(i,6)==x(8))) |  
    ((a(i,5)==x(9)) & (a(i,6)==x(10)) | 
    ((a(i,5)==x(11)) & (a(i,6)==x(12)))))
   q(i,:)=a(i,:);
end;
end;
q;
R1=a-q;
R1(~any(R1,2),:) = [];
R1(:, ~any(R1)) = [];

问题:谁能给出一个想法如何重写if-statement以提高代码的可读性?

【问题讨论】:

  • 除了你之外的任何人都几乎不可能简化这种情况;所有这些组件背后没有任何意义。然而,一个建议是:使用逻辑而不是位操作,因为前者会短路(可能),而后者不会。
  • 另请注意,您的最后一行是一个 OR 案例,而前几行每行包含 2 个案例。这远非简单的条件分割(我会每行使用一个顶级 OR),甚至可能是您这边的错误。
  • 最后一点:如果您将一个数组的排列与另一个数组进行比较,为什么不生成索引而不是值本身,在这种情况下,您可以测试整数的相等性(而不是谁知道什么? )?
  • @AndrasDeak,感谢您的评论,尤其是最后一点,我不考虑世代指数。

标签: matlab if-statement combinations


【解决方案1】:

如果我理解正确的话,复杂的 if 语句基本上是说什么

If "x(1) x(2)" or "x(3) x(4)" or ... "x(11) x(12)" appears anywhere consecutively in row i

想一想:

((a(i,1)==x(1)) & (a(i,2)==x(2))) |  ((a(i,1)==x(3)) & (a(i,2)==x(4))) |
((a(i,1)==x(5)) & (a(i,2)==x(6))) |   ((a(i,1)==x(7)) & (a(i,2)==x(8)))

与:

((a(i,1)==x(1)) & (a(i,2)==x(2))) |  ((a(i,1)==x(3)) & (a(i,2)==x(4))) |
((a(i,1)==x(5)) & (a(i,2)==x(6))) |   ((a(i,1)==x(7)) & (a(i,2)==x(8))) |
((a(i,1)==x(9)) & (a(i,2)==x(10))) |   ((a(i,1)==x(11)) & (a(i,2)==x(12)))

因为[x(9) x(10)][x(11) x(12)] 永远不会出现在a(i, 1:2),所以我添加的行总是假的并且不会改变OR 链的结果。但是如果使逻辑更容易理解。同样的逻辑适用于a(i,2:3), a(i,3:4)...,也完成这些案例,然后您将得到我在此答案中所做的第一个陈述。

那么,不是直接从x生成a,而是应该从xINDEX生成a,即[1:12],如下所示:

a = nchoosek(1:length(x), 6);

为什么?您说x 由实数组成,而在实数上使用== 并不能保证成功,而且通常是一种非常糟糕的做法。

那么,你的目标就变成了:

find if sequence `[1 2]` or `[3 4]` or `[5 6]` ... exists in each line of `a`

相当于:

find if there is any odd number n followed by n+1 

这个逻辑可以表示为:

success = any (mod(a(:,1:end-1), 2) & diff(a,1,2)==1, 2) 

现在success(i) 将是true/false,因为您的语句评估为相同值的每个a(i)。这个方法比你的语句好,因为它非常简洁,自动适应x的不同大小,不需要循环运行。

如果您想获得x 值的实际组合,只需这样做

x(a(i));    % Get the ith permutation of x
x(a);       % Get all permutation of x
x(a(success,:));    % Get all permutation of x that satisfy the requirement.

编辑:

q = a;               % q is basically a copy of a
q(~success,:) = 0;   % except the `non-success` rows are zero 
x(q) - x(a)          % suppose q and a store index, this will give you the substraction.

【讨论】:

  • 感谢您的完整回答,但我不能接受您的解决方案。我已经更新了我的问题。
  • 抱歉,应该是 any(..., 2)。我已经更新了我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2010-10-29
  • 2020-11-10
  • 2015-01-26
相关资源
最近更新 更多