Enumerating k-segmentations of a sequence

Gerard flanagan grflanagan at gmail.com
Tue Nov 25 14:30:04 EST 2008


bullockbefriending bard wrote:
> I'm not sure if my terminology is precise enough, but what I want to
> do is:
> 
> Given an ordered sequence of n items, enumerate all its possible k-
> segmentations.
> 
> This is *not* the same as enumerating the k set partitions of the n
> items because I am only interested in those set partitions which
> preserve the order of the items. i.e. if the input sequence is (1 2 3
> 4 5), then ((1 4) (2 3) (5)) is unacceptable, whereas ((1 2) (3) (4
> 5)) is acceptable. Hence use of term 'segmentations'.
> 
> e.g., for input sequence (1 2 3 4 5) and k = 3, I need a function
> which enumerates the following 3-segmentations:
> 
> ((1 2 3) (4) (5))
> ((1 2) (3 4) (5))
> ((1 2) (3) (4 5))
> ((1) (2 3 4) (5))
> ((1) (2 3) (4 5))
> ((1) (2) (3 4 5))
> 

What Arnaud said.


def nchoosek( n, k ):
     '''
     Generate all subsets of S(n) that have k items.
     S(n) = {1, 2, 3, ..., n}

     >>> list(nksubsets(3, 2))
     [[1, 2], [1, 3], [2, 3]]
     '''
     m = n - k + 1
     indexer = range(0, k)
     seq = range(1, k+1)
     last = range(m, n+1)
     yield seq[:]
     while seq != last:
         high_value = -1
         high_index = -1
         for i in indexer:
             val = seq[i]
             if val > high_value and val < m + i:
                 high_value = val
                 high_index = i
         for j in range(k - high_index):
             seq[j+high_index] = high_value + j + 1
         yield seq[:]

#(minimally tested)
def part(n,k):
     rng = range(1, n+1)
     for comb in nchoosek(n-1,k-1):
         comb = [0] + comb + [n]
         yield [rng[s:t] for (s,t) in (comb[i:i+2] for i in range(k))]


for item in part(5, 2):
     print item

for item in part(5, 3):
     print item

G.




More information about the Python-list mailing list