找到两个相同大小的二进制向量之间的所有映射?

时间:2014-12-29 21:54:52

标签: matlab permutation combinatorics

这与此问题非常相似

Getting the mapping for a permutation in MATLAB

我想知道如何在两个二进制向量之间找到所有可能的映射,其中条目可以重复,并且是1或0。

例如,找到这两个二元向量之间的所有映射

[0 0 0 1 1 0 1 0] 和 [1 1 0 0 0 0 0 1]

3 个答案:

答案 0 :(得分:2)

蛮力方法:生成所有可能的映射(置换),并仅保留第一个向量的图像是第二个向量的映射:

x = [0 0 0 1 1 0 1 0]; %// initial vector
y = [1 1 0 0 0 0 0 1]; %// image vector
maps = perms(1:numel(x)); %// each row is a possible mapping
valid = all(bsxfun(@eq, x(maps), y), 2); %// 1 for mappings that map x to y
maps = maps(valid,:); %// keep only valid mappings

对于您的示例向量,这会将x转换为y的720个映射(40320种可能性)。

答案 1 :(得分:1)

您可以为每个部分进行匹配并合并结果。

以下可能有所帮助(在删除标记之前完成的C ++代码):

// print the combination of the two partial mappings.
// So that print one full mapping.
void print(
    const std::vector<bool>& flags,
    const std::vector<std::size_t>& zeros,
    const std::vector<std::size_t>& ones)
{
    auto it0 = zeros.begin();
    auto it1 = ones.begin();
    for (const auto& b : flags) {
        if (b) {
            std::cout << *it1++ << " ";
        } else {
            std::cout << *it0++ << " ";
        }
    }
    std::cout << std::endl;
}

// Display all full mappings.
void displayMapping(const std::vector<bool>& orig, const std::vector<bool>& target) {
    // same number of one
    assert(std::accumulate(orig.begin(), orig.end(), 0)
        == std::accumulate(target.begin(), target.end(), 0));
    // same number of zero
    assert(orig.size() == target.size());
    std::vector<std::size_t> zeros;
    std::vector<std::size_t> ones;
    // dispatch indexes for partial mapping 
    for (std::size_t i = 0; i != target.size(); ++i) {
        if (target[i]) {
            ones.push_back(i);
        } else {
            zeros.push_back(i);
        }
    }

    do {
        do {
            print(orig, zeros, ones);
        } while (std::next_permutation(zeros.begin(), zeros.end()));
    } while (std::next_permutation(ones.begin(), ones.end()));
}

Live demo

答案 2 :(得分:1)

以下解决方案找到B中可以去零的所有位置(T0),以及可以去的地方(T1)。然后它遍历所有这些排列,产生每个映射。

A = [0 0 0 1 1 0 1 0];
B = [1 1 0 0 0 0 0 1];

l = length(A);

T0 = perms(find(B==0)); % all targets for zeroes
T1 = perms(find(B==1)); % all targets for ones

s0 = find(A==0); % source of zeroes
s1 = find(A==1); % source of ones

nT0 = size(T0,1);
nT1 = size(T1,1);

q = zeros(1,l);

for i = 1:nT0
    t0 = T0(i,:); % current target for zeroes
    for j = 1:nT1
        t1 = T1(j,:); % current target for ones
        q(s0) = t0;
        q(s1) = t1
        % q has a mapping
    end
end