根据某些条件减少载体的细胞

时间:2015-01-25 20:31:38

标签: matlab cell knapsack-problem

A成为向量的单元格。为方便起见,请将这些向量表示为V1V2,...

我想找到一组没有“巧合”的最大矢量集。当任何这些条件成立时,两个向量VnVm之间会发生一致:

  • 这两个向量具有一些共同的价值,即某些Vn(i)==Vm(j)i j
  • 这两个向量在100中有两个不同的值,即某些abs(Vn(i)-Vm(j))==100i的{​​{1}}。

示例:

j

为了不使我的问题复杂化,在几种可能结果之间选择结果并不重要。

1 个答案:

答案 0 :(得分:1)

这是一种蛮力方法:

  1. 根据问题中的规则确定向量之间的“巧合”。
  2. 对于每个可能的子集,通过确定其向量之间是否存在重合来测试其有效性。
  3. 在所有有效子集中,选择一个具有最大向量数的子集。
  4. 这可能是,主要是因为它是暴力(尝试所有可能的子集),其次是因为它使用cellfun和匿名函数。

    内存使用率很低,因为每个子集(由逻辑值向量指定)都是动态定义的。这依赖于可以枚举所有可能子集的集合的事实,并且子集号和子集描述之间的对应关系仅仅是二进制扩展。

    %// STEP 1
    %// Definition of "coincidence" between two vectors x and y:
    f = @(x,y) nnz(ismember(bsxfun(@minus, x(:),y(:).'), [-100 0 100])); %' 
    %// Generate all combinations:
    [ii, jj] = ndgrid(1:numel(A));
    %// Test for each pair of vectors for coincidences:
    M = cellfun(f, A(ii), A(jj)); %// m(k,l)>0 indicates coincidence betwen vectors k and l
    M = triu(M,1); %// consider each pair only once; and disregard self-coincidences
    
    %// STEP 2
    %// Test if each subset is valid, using (part of) matrix M:
    valid = ones(1,2^numel(A)); %// this will store whether each subset is valid
    num = NaN(1,2^numel(A)); %// this will store number of vectors in each subset
    for n = 1:2^numel(A) %// there are 2^numel(A) possible subsets
        s = logical(dec2bin(n-1)-'0'); %// 1: vector is present. 0: is absent
        num(n) = sum(s); %// number of vectors in the subset
        if nnz(M(s,s)) %// if there are coincidences...
            valid(n) = 0; %// ...then this subset is not valid
        end
    end
    
    %// STEP 3
    %// Find *first* (in the order of ss) valid subset with maximum number of elements:
    [~, t] = max(valid.*num); %'// (it'd be easy to output *all* maximum subsets)
    A_solution = A(logical(dec2bin(t-1)-'0'));