【发布时间】:2018-05-11 22:00:12
【问题描述】:
这个问题是由非常具体的组合优化问题引起的,其中搜索空间被定义为向量未排序的具有多重性的离散值集的置换子集的空间。
我正在寻找能够以下列方式找到子集索引的有效(足够快、矢量化或任何其他更聪明的解决方案)函数:
t = [1 1 3 2 2 2 3 ]
是所有可能值的未排序向量,包括其多重性。
item = [2 3 1; 2 1 2; 3 1 1; 1 3 3]
是向量 t 的置换子集的列表。
我需要找到对应于向量 t 的子集项的对应索引列表。因此,对于上述示例,我们有:
item =
2 3 1
2 1 2
3 1 1
1 3 3
t =
1 1 3 2 2 2 3
ind = item2ind(item,t)
ind =
4 3 1
4 1 5
3 1 2
1 3 7
所以,对于 item = [2 3 1],我们得到 ind = [4 3 1],这意味着:
item 处的第一个值“2”对应于位置“4”上 t 处的第一个值“2”, item 处的第二个值“3”对应于位置“3”上 t 处的第一个值“3”,并且 item 处的第三个值“1”对应于位置“1”上 t 处的第一个值“1”。
在 item =[ 2 1 2] 的情况下,我们得到 ind = [4 1 5],这意味着:
item 处的第一个值“2”对应于位置“4”上 t 处的第一个值“2”, item 处的第二个值“1”对应于位置“1”上 t 处的第一个值“1”,并且 item 处的第三个值“2”对应于位置“5”上 t 处的第二个(!!!)值“1”。
对于
item = [1 1 1]
不存在任何解,因为向量t只包含两个“1”。
我当前版本的函数“item2ind”是非常简单的串行代码,可以通过将“for”循环更改为“parfor”循环来简单地并行化:
function ind = item2ind(item,t)
[nlp,N] = size(item);
ind = zeros(nlp,N);
for i = 1:nlp
auxitem = item(i,:);
auxt = t;
for j = 1:N
I = find(auxitem(j) == auxt,1,'first');
if ~isempty(I)
auxt(I) = 0;
ind(i,j) = I;
else
error('Incompatible content of item and t.');
end
end
end
end
但我需要一些更聪明的东西……而且更快:)
较大输入数据的测试用例:
t = 1:10; % 10 unique values at vector t
t = repmat(t,1,5); % unsorted vector t with multiplicity of all unique values 5
nlp = 100000; % number of item rows
[~,p] = sort(rand(nlp,length(t)),2); % 100000 random permutations
item = t(p); % transform permutations to items
item = item(:,1:30); % transform item to shorter subset
tic;ind = item2ind(item,t);toc % runing and timing of the original function
tic;ind_ = item2ind_new(item,t);toc % runing and timing of the new function
isequal(ind,ind_) % comparison of solutions
【问题讨论】:
-
我还没有找到一个明确的解决方案,但是
[~,~,ib]=intersect(item(ii,:),t,'stable');非常接近你想要的,但是它不明白重复的值不是同一个项目。 -
@AnderBiguri 为问题文本添加一些简要说明...
标签: matlab performance vectorization