如何找到列表中的最大项目数,使得某些对在输出中不在一起?

时间:2014-09-30 23:30:24

标签: python algorithm recursion

我有一个数字列表

l = [1,2,3,4,5]

和一个元组列表,它们描述了哪些项目不应该一起出现在输出中。

gl_distribute = [(1, 2), (1,4), (1, 5), (2, 3), (3, 4)]

可能的清单是

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

我想让我的算法给我第二个[2,4,5]

我想要递归地做。 在第一种情况(t1)中,我用除了1st之外的所有项目调用我的递归算法,在第二种情况下(t2)我再次调用它从gl_distribute中删除第一项出现的对。 这是我的算法

def check_distribute(items, distribute):
    i = sorted(items[:])
    d = distribute[:]
    if not i:
        return []
    if not d:
        return i

    if len(remove_from_distribute(i, d)) == len(d):
        return i

    first = i[0]
    rest = items[1:]
    distr_without_first = remove_from_distribute([first], d)

    t1 = check_distribute(rest, d)

    t2 = check_distribute(rest, distr_without_first)
    t2.append(first)

    if len(t1) >= len(t2):
        return t1
    else:
        return t2

remove_from_distribute(items,distr_list)从distr_list中删除包含项目中任何项目的对。

def remove_from_distribute(items, distribute_list):
    new_distr = distribute_list[:]
    for item in items:
        for pair in distribute_list:
            x, y = pair
            if x == item or y == item and pair in new_distr:
                new_distr.remove((x,y))
    if new_distr:
        return new_distr
    else:
        return []

我的输出为[4, 5, 3, 2, 1],显然不正确。你能告诉我这里做错了什么吗?或者你能给我一个更好的方法来解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

我不确定我是否完全理解你的输出,因为我认为4,5和5,2应该是可能的列表,因为它们不在元组列表中:

如果是这样你可以使用itertools来获取组合并使用集合基于gl_distribute列表进行过滤,以查看梳子中不同组合中的任何两个数字是否包含两个不应该在一起的元素,然后获取max

combs = (combinations(l,r) for r in range(2,len(l)))
final = []
for x in combs:
     final += x
res = max(filter(lambda x: not any(len(set(x).intersection(s)) == 2 for s in gl_distribute),final),key=len)

print res
(2, 4, 5)

答案 1 :(得分:1)

我会建议另一种方法。

假设您的列表和发行版已经过排序,列表的长度为n,而您的发行版的长度为m。

首先,创建一个包含所有有效组合的两个元组的列表。这应该是O(n ^ 2)解决方案。 获得列表后,它只是通过有效组合的简单循环,并找到最长的列表。可能有一些更好的解决方案可以进一步降低复杂性。

以下是我的示例代码:

def get_valid():
  seq = [1, 2, 3, 4, 5]
  gl_dist = [(1, 2), (1,4), (1, 5), (2, 3), (3, 4)]
  gl_index = 0
  valid = []
  for i in xrange(len(seq)):
   for j in xrange(i+1, len(seq)):
     if gl_index < len(gl_dist):
       if (seq[i], seq[j]) != gl_dist[gl_index] :
         valid.append((seq[i], seq[j]))
       else:
         gl_index += 1
     else:
       valid.append((seq[i], seq[j]))
  return valid 
>>>> get_valid()
[(1, 3), (2, 4), (2, 5), (3, 5), (4, 5)]
def get_list():
  total = get_valid()
  start = total[0][0]
  result = [start]
  for i, j in total:
    if i == start:
      result.append(j)
    else:
      start = i
      return_result = list(result)
      result = [i, j]
      yield return_result
  yield list(result)
  raise StopIteration
>>> list(get_list())
[[1, 3], [2, 4, 5], [3, 5], [4, 5]]