简体   繁体   中英

Permutations of 1s without leading or trailing 0s in Python or Cpp

I need an efficient way of generating a list of lists exploring all permutations of Nx1s and Kx0s. However I need to remove all leading and trailing 0s and then remove the duplicates. KN will be in the 100s, N will be anywhere between 2 and 20.

I can do this in steps: 1) Create permutations 2) Remove trailing 0s for each list element 3) Remove leading 0s for each list element 4) Remove duplicates

However it takes a very very long time to do the first 3 steps and so I think I need to find a different approach. Here is the code I used:

import itertools

def donewk(k):
  newk = []
  for i in k:
    if i not in newk:
      newk.append(i)
  return newk

n=2;
k=10;
a=(list(itertools.permutations( [1]*n+[0]*(k-2))))
for i,elem in enumerate(a):
    elem = list(elem)
    while not elem[-1]:
        elem.pop()
    while not elem[0]:
        elem.pop(0)
    a[i]=elem;

a=donewk(a)
print(a)

output

[[1, 1], [1, 0, 1], [1, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1]]

Answered in comments by Engineero.

Removing leading and trailing 0s is the same thing as saying it needs to start and end with 1s. Therefor take the permutation with N-2 and then strap the 1's on the ends.

Thanks!

EDIT: I thought Engineero answered the question but in fact he didnt as it doesnt solve the issue of when the space between the first and last 1 in less then K. He did lead to a satisfactory answer.

I created an iterative application. My final application is cpp, but I did a quick prototype in python as a proof of concept. Note in the cpp application instead of appending to my list I will call a separate function which uses the permutation. Feel free to critique to make it more efficient.

import copy
aList = []

def initA(sz=10):
        return [1]+[0]*(sz-2)+[1];

def iterA(buff,level,ix):
    if (level >0):
        for i in range (level,ix):
            a=copy.deepcopy(buff)
            a[i] = 1;
            if level ==1:
                aList.append(a)
            iterA(a,level-1,i);

N=6;
K=10;
for i in range (N-2,K):
    a=initA(i+1)
    a = iterA(a,N-2,i)
print (aList);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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