【问题标题】:Generate all sequences of bits within Hamming distance t生成汉明距离 t 内的所有位序列
【发布时间】:2017-04-10 07:53:40
【问题描述】:

给定一个位向量v,计算具有v的汉明距离1,然后距离为2的位的集合,直到输入参数t。 p>

所以

011  I should get
~~~ 
111
001
010
~~~ -> 3 choose 1 in number
101
000
110
~~~ -> 3 choose 2
100
~~~ -> 3 choose 3

如何有效地计算这个?向量并不总是 3 维,例如它可能是 6。这将在我的真实代码中运行很多次,因此也欢迎一些效率(即使支付更多内存)。


我的尝试:

#include <iostream>
#include <vector>

void print(const std::vector<char>& v, const int idx, const char new_bit)
{
    for(size_t i = 0; i < v.size(); ++i)
        if(i != idx)
            std::cout << (int)v[i] << " ";
        else
            std::cout << (int)new_bit << " ";
    std::cout << std::endl;
}

void find_near_hamming_dist(const std::vector<char>& v, const int t)
{
    // if t == 1
    for(size_t i = 0; i < v.size(); ++i)
    {
        print(v, i, v[i] ^ 1);
    }

    // I would like to produce t == 2
    // only after ALL the t == 1 results are reported
    /* how to? */
}

int main()
{
    std::vector<char> v = {0, 1, 1};
    find_near_hamming_dist(v, 1);
    return 0; 
}

输出:

MacBook-Pro:hammingDist gsamaras$ g++ -Wall -std=c++0x hammingDist.cpp -o ham
MacBook-Pro:hammingDist gsamaras$ ./ham
1 1 1 
0 0 1 
0 1 0 

【问题讨论】:

  • recently 已经回答了这个问题,差不多,尽管你提出的问题不同。
  • @harold 是的,因为它略有不同! :)

标签: c++ algorithm machine-learning bit-manipulation hamming-distance


【解决方案1】:

针对 Kastrinis 的回答,我想验证这是否可以扩展到我的基础示例,如下所示:

#include <iostream>
#include <vector>

void print(std::vector<char>&v)
{
    for (auto i = v.begin(); i != v.end(); ++i)
        std::cout << (int)*i;
    std::cout << "\n";
}

void magic(std::vector<char>& str, const int i, const int changesLeft) {
        if (changesLeft == 0) {
                print(str);
                return;
        }
        if (i < 0) return;
        // flip current bit
        str[i] ^= 1;
        magic(str, i-1, changesLeft-1);
        // or don't flip it (flip it again to undo)
        str[i] ^= 1;
        magic(str, i-1, changesLeft);
}

int main(void) {
        std::vector<char> str = {0, 1, 1};
        print(str);
        size_t len = str.size();
        size_t maxDistance = str.size();
        for (size_t i = 1 ; i <= maxDistance ; ++i) {
                printf("Computing for distance %lu\n", i);
                magic(str, len-1, i);
                printf("----------------\n");
        }
        return 0;
}

输出相同。


PS - 我也是toggling the bit with a different way

【讨论】:

    【解决方案2】:
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    
    void magic(char* str, int i, int changesLeft) {
            if (changesLeft == 0) {
                    printf("%s\n", str);
                    return;
            }
            if (i < 0) return;
            // flip current bit
            str[i] = str[i] == '0' ? '1' : '0';
            magic(str, i-1, changesLeft-1);
            // or don't flip it (flip it again to undo)
            str[i] = str[i] == '0' ? '1' : '0';
            magic(str, i-1, changesLeft);
    }
    
    int main(void) {
            char str[] = "011";
            printf("%s\n", str);
            size_t len = strlen(str);
            size_t maxDistance = len;
            for (size_t i = 1 ; i <= maxDistance ; ++i) {
                    printf("Computing for distance %d\n", i);
                    magic(str, len-1, i);
                    printf("----------------\n");
            }
            return 0;
    }
    

    输出:

    MacBook-Pro:hammingDist gsamaras$ nano kastrinis.cpp
    MacBook-Pro:hammingDist gsamaras$ g++ -Wall kastrinis.cpp 
    MacBook-Pro:hammingDist gsamaras$ ./a.out 
    011
    Computing for distance 1
    010
    001
    111
    ----------------
    Computing for distance 2
    000
    110
    101
    ----------------
    Computing for distance 3
    100
    ----------------
    

    【讨论】:

    • 纯代码没有任何描述?对未来的访客不是很有用...
    • 您想要什么样的描述?这是直截了当的。你递归地接受所有的可能性(或者你翻转一点,或者你不)
    • @GeorgeKastrinis 感谢您的宝贵回复。我发布了answer 验证这可以扩展到我的基础示例,仅供未来用户使用。请看一看,一切都说得通。再次非常感谢您准确而明确的回答!
    【解决方案3】:

    如果汉明距离h(u, v) = k,则u^v 正好设置了k 位。换句话说,在所有掩码m 上计算u ^ m 并设置k 位会给出具有所需汉明距离的所有单词。请注意,这样的掩码集不依赖于u

    也就是说,对于相当小的nt,预计算设置了k 位的掩码集,用于1,t 中的所有k,并根据需要迭代这些集。

    如果您没有足够的内存,您可以即时生成 k 位模式。详情请见this discussion

    【讨论】:

      【解决方案4】:

      首先:在 hamming dist k 位向量和 kardinality k(具有更改位的索引集)的子集(n aka v.size())之间存在双射。因此,我将枚举更改索引的子集。快速浏览 SO 历史会显示 this 参考。当然,您必须跟踪正确的基数。

      考虑效率可能毫无意义,因为无论如何你的问题的解决方案都是指数级的。

      【讨论】:

        猜你喜欢
        • 2013-09-23
        • 2017-09-10
        • 2017-08-02
        • 1970-01-01
        • 2015-03-21
        • 2012-03-10
        • 2014-01-28
        • 1970-01-01
        相关资源
        最近更新 更多