执行输入参数的所有可能排列(二进制样式逻辑)
Posted
技术标签:
【中文标题】执行输入参数的所有可能排列(二进制样式逻辑)【英文标题】:Execute all possible permutations of input parameters (binary style logic) 【发布时间】:2014-03-15 06:28:55 【问题描述】:我正在尝试编写一些代码来为具有未知数量参数的函数提供数据。这个想法是在可能的值范围内为函数提供最小值、中间值和最大值。
例如:
如果函数采用 3 个参数 参数 1 可以接受的范围是 0 - 10 参数 2 可以接受的范围是 20 - 40 参数 3 可接受的范围为 6 - 66myfunction(para1, para2, para3) 我的函数(分钟,分钟,分钟) 我的函数(分钟,分钟,中间) 我的函数(最小值、最小值、最大值) 我的函数(分钟,中,分钟) 我的功能(分钟,中,中) 我的函数(最小值、中间值、最大值) 等等……
所以使用我们上面的例子:
第一次循环时我需要运行 我的函数(0, 20, 0) 下次循环它需要运行 我的函数(0, 20, 36) 下次循环它需要运行 我的函数(0, 20, 66) 等等...
对于所有可能的组合(在本例中为所有 27 个)。 但是,如果参数的数量更改为接受 4,则它需要能够适应,依此类推。我已经考虑将其作为循环或递归进行,但我认为作为循环会更容易理解,但两者都非常有用。 我不想手动执行此操作,因此非常感谢任何帮助。
【问题讨论】:
见varargin
。
【参考方案1】:
对于任意数量的参数(不固定为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
[paramCombsend:-1:1] = ndgrid(paramsend:-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(paramCombsn,:), 1:N, 'uni', 0); %// call myFun
%// with each combination of parameter values
result
变量是一个 1 x N 元胞数组,其中每个元胞包含调用 myFun
并结合 n 个参数的结果。
示例 1:myFun
的输出只是简单地复制了输入(如 @thewaywewalk's answer)。 params
定义如上,所以有3个参数:
>> result1
ans =
0 20 6
>> result2
ans =
0 20 36
>> result3
ans =
0 20 66
>> result4
ans =
0 30 6
>> result5
ans =
0 30 36
等等
示例 2:带有 2 个参数的案例:params = linspace(0,2,3), linspace(0,10,3)
。同样,myFun
只是复制输入:
>> result1
ans =
0 0
>> result2
ans =
0 5
>> result3
ans =
0 10
>> result4
ans =
1 0
>> result5
ans =
1 5
等等
该方法可以进一步推广到每个参数的任意(可能不同)数量的值,只需将N = 3^n;
行替换为
N = prod(cellfun(@numel, params)); %// number of combinations
示例3:有2个参数;第一个有 3 个值,第二个有 2 个:params = [1 2 3], [10 20];
:
>> result1
ans =
1 10
>> result2
ans =
1 20
>> result3
ans =
2 10
>> result4
ans =
2 20
>> result5
ans =
3 10
>> result6
ans =
3 20
【讨论】:
【参考方案2】:想想这样的事情:
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)
ans1 =
10 30 6
ans2 =
10 20 36
ans3 =
5 40 6
ans4 =
5 20 66
ans5 =
0 30 66
ans6 =
0 40 36
【讨论】:
+1 不错的方法。可以使用逗号分隔的列表推广到不确定数量的参数;看我的回答【参考方案3】:这就是我的解决方法:
%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
是一个肮脏的解决方案,但我找不到允许可变输入大小的替代方案。
【讨论】:
以上是关于执行输入参数的所有可能排列(二进制样式逻辑)的主要内容,如果未能解决你的问题,请参考以下文章