Python 在列表中找出矛盾

Python 在列表中找出矛盾,python,list,logic,Python,List,Logic,我有很多清单,我想知道是否有与其他清单相矛盾的清单。 列表本身不会发生冲突,所有关系仅为'>'和'您只需为每个变量维护一个列表,其中包含上限和下限。如果变量没有上限或下限,则可以使用None 每次计算约束时,都会相应地更新列表,当下限大于上限时,我们知道存在冲突 现在我们只需要几个部件: 导出约束的解析步骤 维护和检查边界的变量管理器 变量管理器的工作方式如下: def update_variables(var_dict,variable,constraint,value): la

我有很多清单,我想知道是否有与其他清单相矛盾的清单。
列表本身不会发生冲突,所有关系仅为
'>'
'您只需为每个变量维护一个列表,其中包含上限和下限。如果变量没有上限或下限,则可以使用
None

每次计算约束时,都会相应地更新列表,当下限大于上限时,我们知道存在冲突

现在我们只需要几个部件:

  • 导出约束的解析步骤
  • 维护和检查边界的变量管理器
变量管理器的工作方式如下:

def update_variables(var_dict,variable,constraint,value):
    la = var_dict.get(variable)
    if la is None:
        la = [None,None]
        var_dict[variable] = la
    if constraint == '>' and (la[0] is None or value > la[0]):
        la[0] = value
    elif constraint == '<' and (la[1] is None or value < la[1]):
        la[1] = value
    return la[0] is None or la[1] is None or la[0] < la[1]
因此,这里我们假设每个字符串的格式都是
\w+
(变量的名称),后面是
'
,最后是值
-?\d+
。每次我们从列表中获取这样的字符串,解析它,更新管理器并检查配置是否仍然有效。这看起来像:

import re

def conflict(lista,listb):
    manager = {}
    rgx = re.compile(r'(\w+)\s*(<|>)\s*(-?\d+)')
    for listi in (lista,listb):
        for constraint in listi:
            mat = rgx.match(constraint)
            if mat:
                var,con,val = mat.groups()
                val = int(val)
                if not update_variables(manager,var,con,val):
                    return True # the lists are conflicting
            else:
                raise Exception('Could not parse constraint "%s"'%constraint)
    return False # the lists do not conflict

您可以简单地为每个变量维护一个包含上限和下限的列表。如果变量没有上限或下限,则可以使用
None

每次计算约束时,都会相应地更新列表,当下限大于上限时,我们知道存在冲突

现在我们只需要几个部件:

  • 导出约束的解析步骤
  • 维护和检查边界的变量管理器
变量管理器的工作方式如下:

def update_variables(var_dict,variable,constraint,value):
    la = var_dict.get(variable)
    if la is None:
        la = [None,None]
        var_dict[variable] = la
    if constraint == '>' and (la[0] is None or value > la[0]):
        la[0] = value
    elif constraint == '<' and (la[1] is None or value < la[1]):
        la[1] = value
    return la[0] is None or la[1] is None or la[0] < la[1]
因此,这里我们假设每个字符串的格式都是
\w+
(变量的名称),后面是
'
,最后是值
-?\d+
。每次我们从列表中获取这样的字符串,解析它,更新管理器并检查配置是否仍然有效。这看起来像:

import re

def conflict(lista,listb):
    manager = {}
    rgx = re.compile(r'(\w+)\s*(<|>)\s*(-?\d+)')
    for listi in (lista,listb):
        for constraint in listi:
            mat = rgx.match(constraint)
            if mat:
                var,con,val = mat.groups()
                val = int(val)
                if not update_variables(manager,var,con,val):
                    return True # the lists are conflicting
            else:
                raise Exception('Could not parse constraint "%s"'%constraint)
    return False # the lists do not conflict
你可以试试SymPy

from sympy.solvers import solve
from sympy import symbols
from sympy.parsing.sympy_parser import parse_expr

a, b, c, d = symbols('a b c d')
list1 = ["a<4", "b<3", "c<3", "d<6"]
list2 = ["b<6", "a<1", "c<5", "d<2"]
list3 = ["a>7", "c<2", "b>1", "d<8"]

l1 = [parse_expr(eq) for eq in list1]
l2 = [parse_expr(eq) for eq in list2]
l3 = [parse_expr(eq) for eq in list3]

print(solve(l1 + l2))
print(solve(l1 + l3))
print(solve(l2 + l3))
当然,如果您有许多字符串列表,那么您必须找到一种方法来组合所有列表,就像我在这里手动做的那样,因为只有三种组合
l1+l2
l1+l3
l2+l3
。您还应该注意,对于大型列表,性能可能会变差。

您可以尝试SymPy

from sympy.solvers import solve
from sympy import symbols
from sympy.parsing.sympy_parser import parse_expr

a, b, c, d = symbols('a b c d')
list1 = ["a<4", "b<3", "c<3", "d<6"]
list2 = ["b<6", "a<1", "c<5", "d<2"]
list3 = ["a>7", "c<2", "b>1", "d<8"]

l1 = [parse_expr(eq) for eq in list1]
l2 = [parse_expr(eq) for eq in list2]
l3 = [parse_expr(eq) for eq in list3]

print(solve(l1 + l2))
print(solve(l1 + l3))
print(solve(l2 + l3))


当然,如果您有许多字符串列表,那么您必须找到一种方法来组合所有列表,就像我在这里手动做的那样,因为只有三种组合
l1+l2
l1+l3
l2+l3
。您还应该注意,对于大型列表,性能可能会变差。

变量是否总是位于相同的索引上?代码在哪里,您尝试过了?很抱歉,不清楚,实际上,变量会在不同的索引中更改其位置list@jimmy15923:列表有时会与自身冲突吗,如
list1=[“a2”]
?此外,所有关系是否都是
?请考虑改写你的问题,以更好地说明问题。现在它有很多开放的端点。@WillemVanOnsem不,列表本身不会冲突。变量总是位于相同的索引上吗?代码在哪里,您尝试过了?很抱歉,不清楚,实际上,变量会在不同的索引中改变它们的位置list@jimmy15923:列表有时会与自身冲突吗,如
list1=[“a2”]
?此外,所有关系是否都是
?请考虑改写你的问题,以更好地说明问题。现在它有很多未解决的问题。@WillemVanOnsem不,一个列表本身不会有冲突。这正是我想做的,但没有用。你知道为什么
simplify(和(Rel(a,4,,))
对sympy来说不是
False
吗?我猜
simplify
并没有试图解决这个显然没有解决方案的关系,而是试图简化它。这正是我试图做的,没有用。你知道为什么
simplify(和(Rel(a,4,,))
对sympy来说不是
False
吗?我猜
simplify
并没有试图解决这个显然没有解决方案的关系,而只是试图简化它。我想知道我是否想知道哪个变量是冲突的,我该怎么做?我已经尝试了if la[1]from sympy.solvers import solve from sympy import symbols from sympy.parsing.sympy_parser import parse_expr a, b, c, d = symbols('a b c d') list1 = ["a<4", "b<3", "c<3", "d<6"] list2 = ["b<6", "a<1", "c<5", "d<2"] list3 = ["a>7", "c<2", "b>1", "d<8"] l1 = [parse_expr(eq) for eq in list1] l2 = [parse_expr(eq) for eq in list2] l3 = [parse_expr(eq) for eq in list3] print(solve(l1 + l2)) print(solve(l1 + l3)) print(solve(l2 + l3))
def contradiction(l_i, l_j):
    s = solve(l_i + l_j)
    if s==False: return True
    else: return False