如何用Python求线性方程正整数解?含工具使用疑问
问题解答
1. python-constraint中变量定义域的设置方式
既可以用problem.addVariables()分别设置不同变量的定义域,也可以用problem.addVariable()逐个添加,两种方式都可行:
- 使用
addVariables()时,传入字典即可实现变量的差异化定义域设置:
from constraint import * problem = Problem() # 单独设置a的范围是0-6,b的范围是0-3 problem.addVariables({'a': range(7), 'b': range(4)}) problem.addConstraint(lambda a, b: 5 == 2*b + a, ('a', 'b')) solutions = problem.getSolutions() print(solutions)
- 也可以用
addVariable()逐个添加变量,效果完全一致:
from constraint import * problem = Problem() problem.addVariable('a', range(7)) problem.addVariable('b', range(4)) problem.addConstraint(lambda a, b: 5 == 2*b + a, ('a', 'b')) solutions = problem.getSolutions() print(solutions)
根据个人习惯选择即可,两种方式都能精准控制每个变量的取值范围。
2. 其他Python工具实现方式
SymPy实现及解的提取
SymPy的solve()返回的是参数化通解(线性不定方程本身有无穷多解),要得到指定范围的正整数/非负整数解,需要手动遍历参数并筛选:
方法1:直接遍历参数范围
import sympy a, b = sympy.symbols('a b', integer=True, nonnegative=True) # 约束为非负整数 solutions = [] # 根据方程a=5-2b,b的可能取值范围是0≤b≤2(保证a≥0) for b_val in range(0, 3): a_val = 5 - 2 * b_val if a_val >= 0: # 若要求正整数,改为a_val > 0 solutions.append({'a': a_val, 'b': b_val}) print(solutions)
输出:
[{'a': 5, 'b': 0}, {'a': 3, 'b': 1}, {'a': 1, 'b': 2}]
方法2:使用SymPy丢番图方程模块
SymPy的diophantine模块专门处理整数方程,返回参数化解后再筛选符合条件的结果:
from sympy import diophantine, symbols a, b = symbols('a b', integer=True) # 获取参数化通解 general_sol = diophantine(a + 2*b - 5) solutions = [] # 遍历参数t,保证a、b为非负整数 for t in range(0, 3): a_expr, b_expr = next(iter(general_sol)) a_val = a_expr.subs('t', t) b_val = b_expr.subs('t', t) if a_val >= 0 and b_val >= 0: solutions.append({'a': a_val, 'b': b_val}) print(solutions)
PuLP实现
PuLP是线性规划工具,默认只返回一个可行解,要获取所有解需要循环添加排除约束:
from pulp import LpProblem, LpVariable, LpStatus, value # 创建问题,指定最小化目标(仅为满足框架要求,实际不需要优化) prob = LpProblem("FindIntegerSolutions", LpMinimize) # 定义非负整数变量(lowBound=1则约束为正整数) a = LpVariable("a", lowBound=0, cat='Integer') b = LpVariable("b", lowBound=0, cat='Integer') # 添加方程约束 prob += a + 2*b == 5 # 空目标函数 prob += 0 solutions = [] # 循环求解直到无可行解 while LpStatus[prob.status] == 'Optimal': a_val = int(value(a)) b_val = int(value(b)) solutions.append({'a': a_val, 'b': b_val}) # 添加约束排除当前解,避免重复 prob += (a != a_val) | (b != b_val) prob.solve() print(solutions)
内容的提问来源于stack exchange,提问作者The August
相关产品推荐
相关产品推荐

