set partition question
Arnaud Delobelle
arnodel at googlemail.com
Mon May 26 03:58:28 EDT 2008
pball.benetech at gmail.com writes:
> On May 25, 1:13 pm, "Martin v. Löwis" <mar... at v.loewis.de> wrote:
>> > We can use any operation or function which
>> > takes and returns sets.
>>
>> I think the problem is significantly underspecified. It would be a more
>> interesting problem if there was a restriction to a few selected set
>> operations, e.g. union, intersection, difference, and combinations
>> thereof.
>
> Ok, that's quite right -- when I just tried to define "any function,"
> I found that all the solutions I came up with were combinations of the
> set operations defined for immutable sets. Let me improve the spec as
> the following:
>
> There may be arbitrarily many set elements (denoted by integers
> 1,2,3,...), arbitrarily many combinations of the elements composing
> the sets s_i (s0, s1, ...). We can use any of python's set operations
> or combination of those operations.
OK then, if you only allow union, intersection, difference, symmetric
difference then I think it would be easy to prove (I haven't done it!)
that if there is a solution to you problem, then the method below
yields a solution:
*** warning: all this is untested AND written in a rush ***
let S be the set of all your sets except s0 (i.e. s1, s2, s3, ...)
# X is the "domain", C is the set of complements in X of elements of S
X = reduce(set.union, S)
C = set(X - s for s in S)
# Find the "fibers" at each element x of s0. A fiber at x is the set
# of all s in S or C that contain x
from collections import defaultdict
fibers = defaultdict(list)
for s in S | C:
for x in s & s0:
fibers[x].append(s)
# Find the "seeds" at each x in s0. A seed at x is the set of all
# elements contained in all s in the fiber at x.
# Intutively, a seed at x is the smallest set containing x that can be
# built from S
seeds = [reduce(set.intersection, F) for F in fibers.itervalues()]
# Now we know if there is a solution:
sol = reduce(set.union, seeds)
if sol != s0:
print "No solution"
else:
print "Solution: union(intersection(fibers[x]) for x in s0)"
I think this solution will be found in O(m*n**2) time, where:
* n is the size of X (i.e. the total number of elements)
* m is the size of S (i.e. the total number of sets)
and assuming that set operations are linear.
--
Arnaud
More information about the Python-list
mailing list