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

Python 如何在列表中找到最大项数,以使某些对在输出中不在一起?,python,algorithm,recursion,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)中,我调用递归算法处理除第一项以外的所有项,在第二种情况(t2)中,我再次调用它,从第一项出现的gl_分布中删除对。 这是我的算法 def

我有一张号码表

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)中,我调用递归算法处理除第一项以外的所有项,在第二种情况(t2)中,我再次调用它,从第一项出现的gl_分布中删除对。 这是我的算法

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(项目,分发列表)从分发列表中删除包含项目中任何项目的对

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]
,这显然是不正确的。你能告诉我我做错了什么吗?或者你能给我一个更好的方法来处理这个问题吗?

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

如果是这样,您可以使用itertools获取组合,并基于使用集合的
gl\u 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)

我将建议另一种方法

假设您的列表和分布已排序,列表长度为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]]
def get_valid():
seq=[1,2,3,4,5]
gl_dist=[(1,2)、(1,4)、(1,5)、(2,3)、(3,4)]
gl_指数=0
有效=[]
对于x范围内的i(len(seq)):
对于x范围内的j(i+1,len(seq)):
如果总账索引>>>获取有效值()
[(1, 3), (2, 4), (2, 5), (3, 5), (4, 5)]
def get_list():
总计=获取有效值()
开始=总计[0][0]
结果=[开始]
对于i,j总计:
如果i==开始:
结果追加(j)
其他:
开始=i
返回结果=列表(结果)
结果=[i,j]
收益率结果
产量表(结果)
提出停止迭代
>>>列表(get_list())
[[1, 3], [2, 4, 5], [3, 5], [4, 5]]

那么
4,5
5,2
等等呢。。。我不明白你的,可能的清单are@PadraicCunningham我认为可能的列表意味着可能的最大列表(即不能再添加一个)。问题是如何找到尽可能长的最大列表。如果有两个长度相同的列表,会发生什么情况?效果很好。目前,我不关心两个列表可能大小相同的复杂性或事实。这段代码如何提取最大长度
posible_list=list(get_list())size={len(lst):posible_list中lst的lst}打印大小[max(size)]
use sorted()更简单。您可能需要排序的内容(get_list(),key=len,reverse=True)[0]。谢谢您的回答。你能解释一下res的声明吗?我要处理的很多问题:-基本上,在我们得到所有使用的组合后,
set.intersection
返回两个可比性之间的公共元素,如果在
gl\u distribute
中一个组合和任何元组之间有两个公共元素,那么我们就不保留该组合,最后,我们根据过滤后剩余的所有组合的长度得到最大值