如何用Sympy获取表达式中各变量的有效整数取值范围?
问题描述
给定以下Sympy代码定义的逻辑表达式:
from sympy import * a,b,c,d = var('a b c d') variables = { 'a': a, 'b': b, 'c': c, 'd': d } string = "(a > 1548) | (a > 2090) | (b > 2662) | ((c > 838) & (c < 1801)) | ((d > 2770) & (d < 3448))" expr = eval(string,variables) expr
实际生效的表达式为:
(a > 1548) | (a > 2090) | (b > 2662) | ((c > 838) & (c < 1801)) | ((d > 2770) & (d < 2900))
已知每个变量的取值范围是1到3000,对应的约束表达式为:
valid_expr = expr & ((1 <= a) & (a <= 3000)) & ((1 <= b) & (b <= 3000)) & ((1 <= c) & (c <= 3000)) & ((1 <= d) & (d <= 3000))
需要提取每个变量的有效取值范围,期望得到如下格式的输出:
{ 'a': [1548,3000], 'b': [2662,3000], 'c': [838,1801], 'd': [2770,2900] }
解决方案
利用Sympy的reduce_inequalities函数可单独对每个变量求解约束范围,具体实现如下:
from sympy import * # 定义变量 a, b, c, d = var('a b c d') variables = {'a': a, 'b': b, 'c': c, 'd': d} # 实际表达式 expr = (a > 1548) | (a > 2090) | (b > 2662) | ((c > 838) & (c < 1801)) | ((d > 2770) & (d < 2900)) # 加上变量的全局取值范围约束 valid_expr = expr & ((1 <= a) & (a <= 3000)) & ((1 <= b) & (b <= 3000)) & ((1 <= c) & (c <= 3000)) & ((1 <= d) & (d <= 3000)) # 提取每个变量的有效范围 result = {} for var_name, var in variables.items(): # 对单个变量化简不等式 reduced = reduce_inequalities(valid_expr, var) # 解析结果为区间格式 interval = reduced.as_set().args[0] result[var_name] = [interval.left, interval.right] # 输出结果 print(result)
执行后会输出目标格式的结果:
{'a': [1548, 3000], 'b': [2662, 3000], 'c': [838, 1801], 'd': [2770, 2900]}
关键说明
reduce_inequalities会针对指定变量化简整体约束,自动过滤其他变量的影响as_set()将化简后的不等式结果转换为集合类型,方便直接提取区间的左右边界- 针对变量a的两个
OR条件,函数会自动合并为更简洁的1548 < a <= 3000,对应输出的区间格式
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

