Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > set partitioning

Reply
Thread Tools

set partitioning

 
 
hymort@hotmail.com
Guest
Posts: n/a
 
      05-01-2006
Can someone tell me of a good algorithm to partition a set of n
elements into m non-empty, disjoint subsets, where each subset has size
k?

 
Reply With Quote
 
 
 
 
hymort@hotmail.com
Guest
Posts: n/a
 
      05-01-2006
Also, if I do not care about the number of subsets, what is a good
algorithm to partition a set of n elements into non-empty, disjoint
subsets of size k?

 
Reply With Quote
 
 
 
 
aaronwmail-usenet@yahoo.com
Guest
Posts: n/a
 
      05-01-2006
Something like this, or am I missing something?

def partition(List, n, m, k):
if n!=m*k:
raise "sorry, too many or too few elts"
D = {}
for x in List:
D[x] = 1
if len(D)!=n:
raise "sorry (2) you lied about the number"
List2 = D.keys()
result = []
for i in range(m):
result.append( List2[i*k: i*k+k] )
return result
?

If this was a take home exam problem,
you should be ashamed of yourself!
-- Aaron Watters

===

It's easy. All you have to do is hit
the right keys at the right time and
the organ plays itself. -- J.S. Bach

 
Reply With Quote
 
hymort@hotmail.com
Guest
Posts: n/a
 
      05-01-2006
Hello,

Not quite what I'm looking for. I would like a list of all partitions
with each partition having k or less elements, not just one instance.



aaronwmail-use...@yahoo.com wrote:
> Something like this, or am I missing something?
>
> def partition(List, n, m, k):
> if n!=m*k:
> raise "sorry, too many or too few elts"
> D = {}
> for x in List:
> D[x] = 1
> if len(D)!=n:
> raise "sorry (2) you lied about the number"
> List2 = D.keys()
> result = []
> for i in range(m):
> result.append( List2[i*k: i*k+k] )
> return result
> ?
>
> If this was a take home exam problem,
> you should be ashamed of yourself!
> -- Aaron Watters
>
> ===
>
> It's easy. All you have to do is hit
> the right keys at the right time and
> the organ plays itself. -- J.S. Bach


 
Reply With Quote
 
Michael Ekstrand
Guest
Posts: n/a
 
      05-01-2006
On Mon, May 01, 2006 at 03:42:53PM -0700, wrote:
> Not quite what I'm looking for. I would like a list of all partitions
> with each partition having k or less elements, not just one instance.


def partition(S, k):
parts = []
ct = 0
cp = []
for elem in S:
if ct > k:
parts.append(cp)
cp = []
ct = 0
cp.append(elem)
ct += 1
parts.append(cp)
return parts

> > If this was a take home exam problem,
> > you should be ashamed of yourself!
> > -- Aaron Watters


- Michael

--
mouse, n: a device for pointing at the xterm in which you want to type.
-- Fortune
Visit me on the Web: http://www.elehack.net
 
Reply With Quote
 
hymort@hotmail.com
Guest
Posts: n/a
 
      05-02-2006
For the list [1,2,3,4], I'm looking for the following for k = 2:

[[1,2], [3,4]]
[[1,3], [2,4]]
[[1,4], [2,3]]

for k = 3:

[[1,2,3], [4]]
[[1,2,4], [3]]
[[1,3,4], [2]]
[[2,3,4], [1]]

 
Reply With Quote
 
James Waldby
Guest
Posts: n/a
 
      05-02-2006
"" wrote:
> Can someone tell me of a good algorithm to partition a set of n
> elements into m non-empty, disjoint subsets, where each subset has
> size k?


and later wrote in a separate post
> Also, if I do not care about the number of subsets, what is a good
> algorithm to partition a set of n elements into non-empty, disjoint
> subsets of size k?


and then execrably wrote [ie, top-posted]:
> Not quite what I'm looking for. I would like a list of all partitions
> with each partition having k or less elements, not just one instance.


when Aaron Watters wrote:
> Something like this, or am I missing something?
>
> def partition(List, n, m, k):

[snip Watters' program to partition set of n elements
into m non-empty disjoint subsets, each of size k]

So if n=3 and k=2 and set S={a,b,c}, you would want a list
like the following?
1. {a},{b},{c}
2. {a,b},{c}
3. {a,c},{b}
4. {b,c},{a}

So it appears you need to do 2 things -

(1) Produce a list of additive partitions of n with numbers
not exceeding k. In the S={a,b,c} example, the list contains
(1,1,1) and (2,1). I think you can make the list with work
O(T(n,k)). For values of T(n,k) (ie, "number of partitions of
n in which the greatest part is k, 1<=k<=n") see
http://www.research.att.com/~njas/sequences/A008284 .

(2) For each list from (1), fill in elements from S into each
of the subsets, in canonical order. (Eg, after filling in (1,1,1)
to make {a},{b},{c}, don't produce {a},{c},{b} etc.) See a
combinatorial algorithms book, eg Reingold, for this part.
http://www.amazon.com/gp/product/013...96722?n=283155

-jiw
 
Reply With Quote
 
Edward Elliott
Guest
Posts: n/a
 
      05-02-2006
wrote:

> For the list [1,2,3,4], I'm looking for the following for k = 2:
>
> [[1,2], [3,4]]
> [[1,3], [2,4]]
> [[1,4], [2,3]]


That's not what you asked for the first time. You said you wanted "m
non-empty, disjoint subsets", but the subsets above are clearly not all
disjoint; only those on the same line are. It sounds like what you really
want is the "powerset of non-empty, disjoint partitions of size k".
 
Reply With Quote
 
Boris Borcic
Guest
Posts: n/a
 
      05-02-2006
wrote:
> For the list [1,2,3,4], I'm looking for the following for k = 2:
>
> [[1,2], [3,4]]
> [[1,3], [2,4]]
> [[1,4], [2,3]]
>
> for k = 3:
>
> [[1,2,3], [4]]
> [[1,2,4], [3]]
> [[1,3,4], [2]]
> [[2,3,4], [1]]
>


def pickk(k,N,m=0) :
if k==1 :
return ((n,) for n in range(m,N))
else :
return ((n,)+more for more in pickk(k-1,N,m+1)
for n in range(m,more[0]))

def partitionN(k,N) :
subsets = [frozenset(S) for S in pickk(k,N)]
def exhaust(rest,bound=0) :
if len(rest) < k :
if rest :
yield [sorted(rest)]
else :
yield []
for newbound in range(bound,len(subsets)) :
S = subsets[newbound]
if rest >= S :
sS = [sorted(S)]
for restpart in exhaust(rest-S,newbound+1) :
yield sS+restpart
return exhaust(set(range(N)))

partition = lambda k,S : [[[S[j] for j in S0] for S0 in P0]
for P0 in partitionN(k,len(S))]

>>> partition(2,[1,2,3,4])

[[[1, 2], [3, 4]], [[1, 3], [2, 4]], [[2, 3], [1, 4]]]
>>> partition(3,[1,2,3,4])

[[[1, 2, 3], [4]], [[1, 2, 4], [3]], [[1, 3, 4], [2]], [[2, 3, 4], [1]]]


CAVEAT : insufficiently tested, not proved correct, uncommented, provided as is
 
Reply With Quote
 
Boris Borcic
Guest
Posts: n/a
 
      05-02-2006
I wrote:
>
> def pickk(k,N,m=0) :
> if k==1 :
> return ((n,) for n in range(m,N))
> else :
> return ((n,)+more for more in pickk(k-1,N,m+1)
> for n in range(m,more[0]))
>
> def partitionN(k,N) :
> subsets = [frozenset(S) for S in pickk(k,N)]


while it doesn't otherwise change results, changing this line to

subsets = [frozenset(S) for S in sorted(pickk(k,N))]

provides everything nicely ordered (e.g. lexicographically)

> def exhaust(rest,bound=0) :
> if len(rest) < k :
> if rest :
> yield [sorted(rest)]
> else :
> yield []
> for newbound in range(bound,len(subsets)) :
> S = subsets[newbound]
> if rest >= S :
> sS = [sorted(S)]
> for restpart in exhaust(rest-S,newbound+1) :
> yield sS+restpart
> return exhaust(set(range(N)))
>
> partition = lambda k,S : [[[S[j] for j in S0] for S0 in P0]
> for P0 in partitionN(k,len(S))]
>
> >>> partition(2,[1,2,3,4])

> [[[1, 2], [3, 4]], [[1, 3], [2, 4]], [[2, 3], [1, 4]]]
> >>> partition(3,[1,2,3,4])

> [[[1, 2, 3], [4]], [[1, 2, 4], [3]], [[1, 3, 4], [2]], [[2, 3, 4], [1]]]
>
>
> CAVEAT : insufficiently tested, not proved correct, uncommented,
> provided as is

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Partitioning with Set.divide Peter Szinek Ruby 6 04-30-2007 09:54 AM
Re: partitioning Sartan Dragonbane MCSE 0 04-30-2004 05:29 AM
Re: partitioning Kendal Emery MCSE 2 04-29-2004 09:32 PM
Re: partitioning billyw MCSE 9 04-29-2004 08:29 PM
partitioning no one MCSE 0 04-29-2004 07:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57