【问题标题】:Finding subsets of a set of vectors that fulfill some conditions找到满足某些条件的一组向量的子集
【发布时间】:2015-02-14 04:39:25
【问题描述】:

在对这个问题进行了所有审核之后,我进行了更改以使其更清晰、更简单。

为了解决这个问题,我有一个矩阵A 和一个行向量A(1,2:7)(行引用),其中至少包含一个0

来自矩阵A

A=[1   2 0 1 2 0 0   0
   2   1 1 1 0 2 2   0
   3   0 0 0 0 1 1   1
   4   0 2 0 1 1 1   2
   5   0 0 0 0 0 1   0
   6   1 0 1 1 2 0   2
   7   1 1 2 2 2 1   1
   8   0 1 1 2 2 0   0
   9   0 1 1 2 2 0   0
  10   2 2 2 2 0 0   1]

除了A(1,2:7)之外,我还想找到满足以下条件的向量A(k,2:7),k≠1 and A(k,8)=0的一个或所有组合:

  1. 组合仅由满足的向量组成 A(k,8)=0; k=1,..,10

  2. 我不会在结果中考虑 A(7,2:7),因为它不包含任何 0。

  3. 如果{A(1,2:7),A(j,2:7)} 是给定的组合,这意味着 低于A(1,n)≠0A(j,n)≠0n = 2,...,7。 (至少其中之一 A 中同一列上的两个值应该是 不同于0)

  4. 一个组合可以包含两个或多个向量。另一个例子: 如果{A(1,2:7),A(j,2:7),A(p,2:7)} 是一个给定的组合,这意味着 小于A(1,n)≠0A(j,n)≠0A(p,n)≠0n = 2,...,7。 (至少三个相同的值之一 A 中的列,应该不同于 0)

  5. 对于矩阵A{A(1,2:7),A(2,2:7)} 是一个组合 满足期望的条件。但我不想拥有一个 组合这样的{A(1,2:7),A(2,2:7),A(3,2:7)},因为A(1,2:7)A(2,2:7) 足以形成一种组合。

对于向量的组合,我必须以一个向量作为参考,在这种情况下它是向量A(1,2:7)。这是我们要补偿其零点的向量。所以A(1,2:7) 通过它的非零分量:2,1 和 2 在关联中做出贡献。

当我在上面说“我想找到...除了A(1,2:7)”时,这在A(1,2:7) 是行引用时有效。但是如果A(5,2:7) 是行引用,在这种情况下句子就变成了“除了A(5,2:7)”。

我真正的问题A 是一个700x8 矩阵。这里AA(1,2:7)A(7,2:7) 只是一个例子,我更喜欢矩阵A 的任意向量A(k,2:7) 的解决方案,A(k,8)=0 和至少其中一个组件是0

【问题讨论】:

  • 我真的很想知道为什么人们对这个问题投反对票!!!
  • 因为它曾经(现在仍然是)以非常混乱的方式编写。
  • 即使你说你让它更清晰、更简单,你只是让它变得更长。顺便说一句:以某种方式改变您的问题是一个非常糟糕的主意,这会改变最初的意图。如果你不断改变你的要求,没有人会愿意尝试回答它。您应该只更改问题以使您的要求更清楚,而不是更改您要求的内容。另外:我已经告诉过你,整个 (2:6) 业务只会让它变得比它需要的更复杂。另外:你的问题是什么?
  • 也许你可以解释你想要达到的目标。这个问题的写法让人感觉您是在要求我们以特定(奇怪)的方式解决您的问题,而不是寻求帮助来解决一般问题。 -- 有一阵子我以为你在找基地,但有些问题又与此冲突。

标签: algorithm matlab matrix


【解决方案1】:

这个问题有点复杂,很难理解。无论如何,我尝试编写一些代码以尽我对问题的理解。这是找到可能组合的部分:

% input matrix
A=[1   2 0 1 2 0 0   0
   2   1 1 1 0 2 2   0
   3   0 0 0 0 1 1   1
   4   0 2 0 1 1 1   2
   5   0 0 0 0 0 1   0
   6   1 0 1 1 2 0   2
   7   1 1 2 2 2 1   1
   8   0 1 1 2 2 0   0
   9   0 1 1 2 2 0   0
  10   2 2 2 2 0 0   1];

% start by considering all rows
rowsIndices = (1:size(A,1))';
rIdx = true(size(rowsIndices));

% exclude 7th row (i.e rows with no zeros in columns 2:7)
%idx(~any(A(:,2:7)==0,2)) = false;
rIdx(7) = false;

% exclude rows that dont have zero in column 8
rIdx(A(:,8) ~= 0) = false;

% for each possible n-combinations
N = sum(rIdx);
combs = cell(1,N);
for k=2:N
    % all combinations of k-rows
    combsK = nchoosek(rowsIndices(rIdx), k);

    % must involve first row
    combsK = combsK(any(combsK==1,2),:);

    % exclude from current k-combinations if there are smaller ones
    if k > 2
        combsKIdx = true(size(combsK,1),1);
        for kk=2:k-1
            if isempty(combs{kk}), continue, end
            for i=1:size(combs{kk},1)
                combsKIdx(sum(ismember(combsK,combs{kk}(i,:)),2)==kk) = false;
            end
        end
        combsK = combsK(combsKIdx,:);
    end

    % for every possible combination, each column 2:7 must not be all zeros
    combsKIdx = true(size(combsK,1),1);
    for i=1:size(combsK,1)
        combsKIdx(i) = all(any(A(combsK(i,:),2:7),1));
    end
    combsK = combsK(combsKIdx,:);

    % store combinations found
    combs{k} = combsK;
end

% display results
celldisp(combs)

这是我得到的组合:

combs{1} =
     []
combs{2} =
     1     2
combs{3} =
     1     5     8
     1     5     9
combs{4} =
     []
combs{5} =
     []

换句话说,三种组合;第一个是 [1 2] 行,第二个是 [1 5 8],第三个是 [1 5 9] 行。

我遗漏的部分是计算找到的每个组合的“分数”的最后一步。老实说,我不明白如何,描述令人困惑!所以我会把这部分留给你..

【讨论】:

  • @bzak:好的,我已经基于此更新了我的答案。它是否给出了预期的结果?显然你仍然需要做贡献分数部分(我仍然不确定你是如何计算的)。
  • @Amro:感谢您试一试!
  • @bzak:我有几个问题要问你。首先,您是否更改了要查找必须涉及A(1,2:7) 的组合的要求(这就是它在粗体声明中所说的)?你的例子表明并非如此!其次,您回到使用列2:6 而不是2:7,现在是什么?第三,假设你找到了一个组合,你怎么知道哪个是参考向量?最后,我还是不明白你说的associate the value i+10 to the vector that contributes by at least one 1, and value i to the vector which contributes only by values equal to 2是什么意思?
  • @Amro:1-我没有改变我的要求,只是我忘了说这只是一个例子,便于理解我的问题,可以选择任何向量。 2- 我总是使用 2:7,这是一个错误,对不起! 3- 参考向量是我最初选择用来补偿他们的零点的向量。 4- 对于向量 Vi(i:行索引),在最终结果中,如果 Vi 在组合中贡献了至少一个 1 以平衡参考向量中 0 的存在,我将 Vi 替换为值 i+10,并且如果 Vi 仅贡献等于 2 的值,我将 Vi 替换为值 i。
  • @Amro:我低估了你的回答:)
【解决方案2】:

如果我已经正确理解了这里对要求的复杂得令人难以置信的描述,那么您想要:

  • 包含一个特定参考行的最小行集
  • 它们的最后一列都有一个零,并且“数据”列中至少有一个零
  • 这样一组行在每个“数据”列中至少包含一个非零元素
    • 然后对生成的索引进行一些摆弄

因为我最近几天碰巧在做类似的事情,所以这很好而且很新鲜。这是一个简单的蛮力方法 - 如果需要考虑更大数据的效率,则需要替换预先生成的所有组合(我最终编写了一个递归迭代器,它为每个组合调用一个回调函数,但我会留下那个在这里为简单起见)。我假设根据示例,第一列将始终包含相关的原始索引 - 这使得在不丢失跟踪的情况下将数据分开非常容易,并且将数据分开有助于在一定程度上简化逻辑。

示例设置:

A=[1   2 0 1 2 0 0   0
   2   1 1 1 0 2 2   0
   3   0 0 0 0 1 1   1
   4   0 2 0 1 1 1   2
   5   0 0 0 0 0 1   0
   6   1 0 1 1 2 0   2
   7   1 1 2 2 2 1   1
   8   0 1 1 2 2 0   0
   9   0 1 1 2 2 0   0
  10   2 2 2 2 0 0   1];
% data columns
colidx = 2:7;
% reference row
refidx = 1;
indices = findindices(A, refidx, colidx)
% then muck about with the indices as need be

功能:

function indices = findindices(A, refidx, colidx)
% pick out the relevant rows
setidx = (A(:,8) == 0) & ~all(A(:,colidx), 2) & (A(:,1) ~= refidx);
ref = A(refidx, :);
rows = A(setidx, :);
% no need to pass any more than the columns of interest here
c = findcombination(ref(colidx), rows(:,colidx));
% turn the combination of 'rows' indices back into the original ones,
indices = [ref(1); rows(c, 1)];
end

function c = findcombination(ref, rows)
n = size(rows, 1);
% search all 1-combinations first, then 2-combinations, etc.
% to ensure we find the smallest first.
for k=1:n
    for c = nchoosek(1:n, k)'
        set = [ref; rows(c,:)];
        if any(set, 1) % true if all columns have at least one nonzero
            return;   % c contains the combination in terms of the rows array
        end
    end
end
c = [];
error('no valid combination!')
end

以及示例数据的结果:

>> test

indices =

    1
    2

【讨论】:

  • 感谢您的回答!我可以把你的程序“refidx = p;”使其对其他参考行有效?
  • 如果我想要 A(5,2:7) 作为参考行,我必须改变什么?
  • findindices(A,5,2:7) 给出:???在 26 处使用 ==> findindices>findcombination 时出错,没有有效的组合! ==> findindices 中的错误 7 c = findcombination(ref(colidx), rows(:,colidx)); ==> 在 18 个索引处过滤时出错 = findindices(A, refidx, colidx)
  • findindices(A,5,2:7) 给出:indices = 15 11 12。虽然这不是一个好结果!因为 11 12 是一个足够的组合
  • "我想找一个向量A(k,2:7),k≠1和A(k,8)=0的组合,除了A(1,2 :7)" 向我暗示您希望将参考行 (1) 明确包含在集合中,因此我在答案顶部列出了解释。如果我的解释是错误的,请尝试更笼统地指定条件,并减少令人困惑的具体细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 2020-12-06
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多