【问题标题】:Partition of a set in pythonpython中集合的分区
【发布时间】:2017-05-31 18:02:11
【问题描述】:

我有b buckets 0....b-1 和m apples 0....m-1。一开始所有的苹果都放在0号桶里。

然后运行一些分析会导致苹果在桶中移动。我已经通过一个 2D 列表(作为存储桶)实现了这一点,其中苹果 id 在需要在存储桶之间移动时被删除和附加。然而,这对我的分析来说是非常低效的,因为这些运动是数百万或数十亿的数量级。所以,我想知道是否有更好的解决方案来实现这样的结构?

顺便说一下,选择标题是因为这与集合问题的分区非常相似,其中任何成员都不能放在超过 1 个子集中。这里还举个例子,用 4 个苹果和 3 个水桶来说明更清楚:

time 0:
a=[[0,1,2,3],[],[]]
time 1: (say apple 3 needs to be moved to bucket 2)
a=[[0,1,2],[],[3]]

【问题讨论】:

    标签: python set subset partition


    【解决方案1】:

    从列表中删除一个元素的问题在于它需要O(n):它需要按照列表中元素数量的顺序来删除它项目。

    你最好使用sets,甚至更好的是bitarray,它可以在O(1)中工作。

    例如:

    m = 50 #the number of apples
    b = 10 #the number of buckets
    fls = [False]*m
    a = [bitarray(fls) for _ in range(b)]
    a[0] = bitarray([True]*m) #add a filled bucket at index 0
    
    def move_apple(apple_id,from_bucket,to_bucket):
        a[from_bucket][apple_id] = False
        a[to_bucket][apple_id] = True
    

    【讨论】:

    • [False for _ in range(m)] 太过分了。对于不可变对象,您可以使用[False]*m。使用bitarray 是一个非常好的主意。
    • 不客气(那是次要的)。我冒昧地稍微编辑了你的帖子顺便说一句。删除了“(带套)”并将“更好”固定为“更好”。这样好多了:)
    • 如果你展示了一些计时实验,将性能与布尔列表进行比较,那就太棒了。
    • @juanpa.arrivillaga:如果今晚我有时间,我会努力解决这个问题......
    【解决方案2】:

    只需使用一个数组来存储每个苹果的桶号吗?

    time 0:
    a=[0,0,0,0]
    time 1: (say apple 3 needs to be moved to bucket 2)
    a=[0,0,0,2]
    

    【讨论】:

    • 我需要反向结构以避免稍后在我的脚本中使用索引。 Index() 也很重。 O(n) 我假设。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2019-04-11
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多