我有一个变量pth
,它是维的单元格数组,1xn
其中n
是用户输入。中的每个元素pth
本身就是一个单元数组,并且length(pth{k})
fork=1:n
是可变的(另一个函数的结果)。每个元素pth{k}{kk}
其中k=1:n
和kk=1:length(pth{k})
是一个一维向量,该向量是整数/节点号,且长度可变。因此,总而言之,我将可变数目的可变长度向量组织在大量的单元格数组中。
我想尝试并找到所有可能的十字路口,当你把一个向量从随机pth{1}
,pth{2}
,{pth{3}
,等...还有对文件交换,似乎要做到这一点,例如各种功能这一个或这一个。我的问题是您需要以这种方式调用该函数:
mintersect(v1,v2,v3,...)
而且我无法写出一般情况下的所有输入,因为我不明确知道有多少输入(将在n
上面)。理想情况下,我想做这样的事情;
mintersect(pth{1}{1},pth{2}{1},pth{3}{1},...,pth{n}{1})
mintersect(pth{1}{1},pth{2}{2},pth{3}{1},...,pth{n}{1})
mintersect(pth{1}{1},pth{2}{3},pth{3}{1},...,pth{n}{1})
etc...
mintersect(pth{1}{1},pth{2}{length(pth{2})},pth{3}{1},...,pth{n}{1})
mintersect(pth{1}{1},pth{2}{1},pth{3}{2},...,pth{n}{1})
etc...
继续研究所有可能的组合,但是我无法用代码编写。来自File Exchange的此函数看起来是查找所有可能组合的好方法,但是同样,对于可变数量输入的函数调用,我也遇到相同的问题:
allcomb(1:length(pth{1}),1:length(pth{2}),...,1:length(pth{n}))
当您无法物理地指定所有输入参数,因为它们的数量是可变的时,有人知道如何解决带有可变数量的输入参数的函数调用的问题吗?这同样适用于MATLAB和Octave,因此也适用于两个标签。关于从每次pth{k}
欢迎中随机抽取向量时如何找到所有可能的组合/交叉点的任何其他建议!
编辑27/05/20
感谢Mad Physicist的回答,我最终使用了以下有效的方法:
disp('Computing intersections for all possible paths...')
grids = cellfun(@(x) 1:numel(x), pth, 'UniformOutput', false);
idx = cell(1, numel(pth));
[idx{:}] = ndgrid(grids{:});
idx = cellfun(@(x) x(:), idx, 'UniformOutput', false);
idx = cat(2, idx{:});
valid_comb = [];
k = 1;
for ii = idx'
indices = reshape(num2cell(ii), size(pth));
selection = cellfun(@(p,k) p{k}, pth, indices, 'UniformOutput', false);
if my_intersect(selection{:})
valid_comb = [valid_comb k];
endif
k = k+1;
end
我自己的版本与此类似,但使用for
循环而不是用逗号分隔的列表:
disp('Computing intersections for all possible paths...')
grids = cellfun(@(x) 1:numel(x), pth, 'UniformOutput', false);
idx = cell(1, numel(pth));
[idx{:}] = ndgrid(grids{:});
idx = cellfun(@(x) x(:), idx, 'UniformOutput', false);
idx = cat(2, idx{:});
[n_comb,~] = size(idx);
temp = cell(n_pipes,1);
valid_comb = [];
k = 1;
for k = 1:n_comb
for kk = 1:n_pipes
temp{kk} = pth{kk}{idx(k,kk)};
end
if my_intersect(temp{:})
valid_comb = [valid_comb k];
end
end
在这两种情况下,valid_comb
都有有效组合的索引,然后可以使用类似的方法检索:
valid_idx = idx(valid_comb(1),:);
for k = 1:n_pipes
pth{k}{valid_idx(k)} % do something with this
end
当我基准一些样品数据的两种方法(pth
是4x1
和的4个元素pth
是2x1
,9x1
,8x1
和69x1
),我得到了以下结果:
>> benchmark
Elapsed time is 51.9075 seconds.
valid_comb = 7112
Elapsed time is 66.6693 seconds.
valid_comb = 7112
因此,疯狂物理学家的方法要快15秒钟左右。
我也误解了mintersect
那是什么,那不是我想要的。我想找到一个组合,其中两个或多个向量中不存在任何元素,因此我结束了我的版本mintersect
:
function valid_comb = my_intersect(varargin)
% Returns true if a valid combination i.e. no combination of any 2 vectors
% have any elements in common
comb_idx = combnk(1:nargin,2);
[nr,nc] = size(comb_idx);
valid_comb = true;
k = 1;
% Use a while loop so that as soon as an intersection is found, the execution stops
while valid_comb && (k<=nr)
temp = intersect(varargin{comb_idx(k,1)},varargin{comb_idx(k,2)});
valid_comb = isempty(temp) && valid_comb;
k = k+1;
end
end
构建解决方案的几个有用点:
因此,让我们ndgrid
从最外面的数组获取输入:
grids = cellfun(@(x) 1:numel(x), pth, 'UniformOutput', false);
现在,您可以创建一个包含网格乘积的索引:
index = cell(1, numel(pth));
[index{:}] = ndgrid(grids{:});
您想将所有网格变成列向量并将其横向连接。该矩阵的行将代表笛卡尔索引,以便pth
在每次迭代时选择的元素:
index = cellfun(@(x) x(:), index, 'UniformOutput', false);
index = cat(2, index{:});
如果将一行index
转换为一个单元格数组,则可以pth
逐步进行操作以选择正确的元素并调用mintersect
结果。
for i = index'
indices = num2cell(i');
selection = cellfun(@(p, i) p{i}, pth, indices, 'UniformOutput', false);
mintersect(selection{:});
end
这是在假设pth
是行数组的情况下编写的。如果不是这种情况,则可以将循环的第一行更改indices = reshape(num2cell(i), size(pth));
为一般情况,而仅indices = num2cell(i);
将列情况更改为。关键是from的单元格indices
必须具有相同的形状,pth
以便在步调上对其进行迭代。它已经生成为具有相同数量的元素。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句