简体   繁体   English

具有顺序的二进制掩码的 N 个排列

[英]N permutations of binary mask with order

I have 'ideal' binary mask, eg: 0000 , and I need to get n most similar variations of it.我有“理想的”二进制掩码,例如: 0000 ,我需要得到它的n最相似的变体。 Change of a left bit is more preferable in sense of similarity.在相似的意义上,左比特的改变是更优选的。 So if n == 5, then I will get following variations:因此,如果 n == 5,那么我将得到以下变化:

1000
0100
0010
0001
1100

I thought about backtracking algorithm, but how can I maintain order then?我想过回溯算法,但是我怎样才能维持秩序呢? What algorithm is the best fit for this?什么算法最适合这个?

All you need is this.你所需要的就是这个。

binval = 1
base = binval
BITWIDTH = 4

for i in range(5):
    if binval & 1:
        binval = base >> 1 | 1 << (BITWIDTH-1)
        base = binval
    else:
        binval >>= 1
    print(f'{binval:0{BITWIDTH}b}')

Output: Output:

1000
0100
0010
0001
1100

You can take advantage of the fact that itertools.combinations returns the combinations in the definite order that you're looking for.您可以利用itertools.combinations以您正在寻找的明确顺序返回组合的事实。

We can generate combinations of 0, 1, 2... 4 positions where the '1' bits have to be, and create your string accordingly.我们可以生成 0、1、2...4 个位置的组合,其中“1”位必须是,并相应地创建您的字符串。

A generator yielding your masks could be:产生你的面具的生成器可能是:

def masks(ideal):
    size = len(ideal)
    positions = list(range(size))  # will be for example [0, 1, 2, 3]

    # we start with 0 flipped bit, then one, up to all
    for nb_flipped in range(0, size+1):
        # we get all combinations of positions where to flip that many bits
        for flipped_positions in combinations(positions, r=nb_flipped):
            out = list(ideal)
            # and we flip the bits at these positions
            for pos in flipped_positions:
                out[pos] =  '1' if out[pos] == '0' else '0'
            yield ''.join(out)

And you can use it like this:你可以像这样使用它:

for m in masks('0000'):
    print(m)
    
# 0000
# 1000
# 0100
# 0010
# 0001
# 1100
# 1010
# 1001
# 0110
# 0101
# 0011
# 1110
# 1101
# 1011
# 0111 
# 1111 
    

If you want a list of the n first ones, you could use a function like:如果您想要前n个列表,您可以使用 function ,例如:

def list_of_masks(ideal, n):
    return list(islice(masks(ideal), n))
    

On your sample ideal mask, this gives:在您的示例理想面具上,这给出:

print(list_of_masks('0101', 6))

# ['0101', '1101', '0001', '0111', '0100', '1001']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM