执行所有可能的输入参数排列(二进制样式逻辑)

时间:2014-02-15 21:43:16

标签: matlab loops combinations

我正在尝试编写一些代码,这些代码为具有未知数量参数的函数提供信息。我们的想法是在可能的值范围内为函数提供最小值,中间值和最大值。

例如:

  • 如果该功能需要3个参数
  • 参数1可以接受0 - 10
  • 的范围
  • 参数2可以接受20 - 40
  • 的范围
  • 参数3可以接受6 - 66
  • 的范围

myfunction(para1,para2,para3)
myfunction(min,min,min)
myfunction(min,min,mid)
myfunction(min,min,max)
myfunction(min,mid,min)
myfunction(min,mid,mid)
myfunction(min,mid,max)
等...

所以使用上面的例子:

第一次循环我需要运行
myfunction(0,20,0)
下次循环时需要运行
myfunction(0,20,36)
下次循环时需要运行
myfunction(0,20,66)
等......

对于所有可能的组合(在这种情况下全部为27)。
但是,如果参数的数量变为接受4,则需要能够容纳该等等。我已经考虑过将它作为一个循环或递归地进行,但我认为循环会更容易理解,但要么真的很有帮助。

我不想手动执行此操作,因此非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

想想这样的事情:

function result = permfunction() 

% I assume you every parameter-range is defined by 3 values: min, mid, max
% you can define every triple as follows:
para1 = linspace(0,10,3);
para2 = linspace(20,40,3);
para3 = linspace(6,66,3);

% all possible parameters
parameters = [para1(:),para2(:),para3(:)];

% possible combinations of parameters-indices
a = perms(1:3);  
% transformed into a cell array with linear indices, to achieve this +3 and +6 
% are added to the 2nd and 3rd row.

idx = mat2cell( [a(:,1) , a(:,2)+3 , a(:,3)+6] , ones(length(a),1) );

% all parameter combinations
combinations = cellfun(@(x) parameters(x),idx,'uni',0');

% apply to your function myfunction (custom)
result = cellfun(@myfunction, combinations,'uni',0' );

end

function y = myfunction( parametertriple )

%just pass the input to the output
y = parametertriple;

end

你最终得到一个包含myfunction结果的单元格数组,用于所有参数组合。在这种情况下,我只是将参数传递给输出:

>> celldisp(ans)

ans{1} =

    10    30     6

ans{2} =

    10    20    36

ans{3} =

     5    40     6

ans{4} =

     5    20    66

ans{5} =

     0    30    66

ans{6} =

     0    40    36

答案 1 :(得分:3)

对于任意数量的参数(未固定为3),您可以使用以下代码。它使用comma-separated lists,这是一个处理可变数量参数的强大工具。

设n为参数个数。然后组合的数量是N = 3 ^ n。

params = {linspace(0,10,3), linspace(20,40,3), linspace(6,66,3)};
%// cell array with arbitrary number of elements. Each cell contains a 3-vector
%// which defines min, mid, max of one parameter.

n = numel(params); %// number of parameters
N = 3^n; %// number of combinations
paramCombs = cell(1,n); %// initialization for output of ndgrid
[paramCombs{end:-1:1}] = ndgrid(params{end:-1:1}); %// generate all combinations
%// in desired order. Gives n matrices, each containing values of one parameter
paramCombs = cellfun(@(c) c(:), paramCombs, 'uni', 0); %// linearize matrices
%// into n column vectors, each with N rows.
paramCombs = [paramCombs{:}]; %// concat column vectors into N x n matrix
paramCombs = mat2cell(paramCombs,ones(N,1),ones(n,1)); %// convert to
%// N x n cell array. Each row contains a combination of parameter values
result = arrayfun(@(n) myFun(paramCombs{n,:}), 1:N, 'uni', 0); %// call myFun
%// with each combination of parameter values

result变量是1 x N单元格数组,其中每个单元格包含使用n个参数组合调用myFun的结果。

示例1 myFun的输出只是复制输入(如@thewaywewalk's answer中所示)。 params的定义如上所述,因此有3个参数:

>> result{1}
ans =
     0    20     6
>> result{2}
ans =
     0    20    36
>> result{3}
ans =
     0    20    66
>> result{4}
ans =
     0    30     6
>> result{5}
ans =
     0    30    36

示例2 :包含2个参数的案例:params = {linspace(0,2,3), linspace(0,10,3)}。同样,myFun只是复制输入:

>> result{1}
ans =
     0     0
>> result{2}
ans =
     0     5
>> result{3}
ans =
     0    10
>> result{4}
ans =
     1     0
>> result{5}
ans =
     1     5

该方法可以进一步推广为每个参数的任意(可能不同)数量的值,只需将行N = 3^n;替换为

N = prod(cellfun(@numel, params)); %// number of combinations

示例3 :有2个参数;第一个有3个值,第二个有2:params = {[1 2 3], [10 20]};

>> result{1}
ans =
     1    10
>> result{2}
ans =
     1    20
>> result{3}
ans =
     2    10
>> result{4}
ans =
     2    20
>> result{5}
ans =
     3    10
>> result{6}
ans =
     3    20

答案 2 :(得分:0)

这就是我要解决的问题:

%dummy function
testfun=@(a,b,c)fprintf('call function for %d,%d,%d\n',a,b,c);
%functon name
testfunname='testfun';
%intended inputs
input={[0,5,10],[20,30,40],[6,36,66]};
%generate all inputs
eval(['[' sprintf('a{%d} ',1:numel(input)) ']=meshgrid(input{:});']);
%call function
eval(['arrayfun(' testfunname sprintf(',a{%d} ',1:numel(input)) ');']);

使用eval是一个肮脏的解决方案,但我没有找到允许变量输入大小的替代方案。