简介:我成功地使用rSymPy库来象征性地解决以下示例系统的平等问题。
x + y = 20; x + 2y = 10
library(rSymPy)
sympy("var('x')")
sympy("var('y')")
sympy("solve([
Eq(x+y, 20),
Eq(x+2*y, 10)
],
[x,y])")
# output
#[1] "{x: 30, y: -10}"
用例:在我的用例中,我想象征性地解决一个混合的平等和不平等系统。这是一个可重现的例子: x + y = 20; x + 2y> 10
不平等可以用Gt
在rSymPy中成功编码:
sympy("Gt(x+2*y, 10)")
# output
# [1] "10 < x + 2*y"
问题:混合系统的代码遇到错误:
sympy("solve([
Eq(x + y, 20),
Gt(x+2*y, 10)
],
[x,y])")
# output
# Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl, :
# Traceback (most recent call last):
# File "<string>", line 1, in <module>
# File "/Users/.../R/3.0/library/rSymPy/Lib/sympy/solvers/solvers.py", line 308, in solve
# raise NotImplementedError()
# NotImplementedError
问题:如何成功重构代码以解决混合系统问题?
答案 0 :(得分:4)
1)定义一个正变量z
。然后,系统可以在z
:
x <- Var('x')
y <- Var('y')
z <- Var('z')
sympy("solve( [ Eq(x+y, 20), Eq(x + 2*y - z, 10) ], [x, y] )")
,并提供:
[1] "{x: 30 - z, y: -10 + z}"
2)这是一个线性编程问题,所以如果您只是寻找约束的任何可行解决方案,那么lpSolve package可以提供这样的解决方案。在这种情况下,它给出了对应于(1)中的z=10
的解决方案:
library(lpSolve)
out <- lp(, c(0, 0), matrix(c(1, 1, 1, 2), 2), c("=", ">"), c(20, 10))
out$solution
## [1] 20 0
ADDED 第一个解决方案,以回应海报的评论。增加了一些进一步的讨论。
答案 1 :(得分:1)
看起来NotImplmentedError
本身就是SymPy
。看起来它无法解决多元不等式。它只能减少它们(这就是你的例子所做的)。该库似乎不支持该类型的系统。
def _solve_inequality(ie, s, assume=True):
""" A hacky replacement for solve, since the latter only works for
univariate inequalities. """
if not ie.rel_op in ('>', '>=', '<', '<='):
raise NotImplementedError
expr = ie.lhs - ie.rhs
try:
p = Poly(expr, s)
if p.degree() != 1:
raise NotImplementedError
except (PolynomialError, NotImplementedError):
try:
n, d = expr.as_numer_denom()
return reduce_rational_inequalities([[ie]], s, assume=assume)
except PolynomialError:
return solve_univariate_inequality(ie, s, assume=assume)
a, b = p.all_coeffs()
if a.is_positive:
return ie.func(s, -b/a)
elif a.is_negative:
return ie.func(-b/a, s)
else:
raise NotImplementedError
答案 2 :(得分:0)
与此同时,我发现了优秀的LIM package,它很好地允许符号解决各种线性逆问题:
ASCII文件linprog.lim
包含人类可读形式的符号问题(它与R代码位于同一目录中):
## UNKNOWNS
X
Y
## END UNKNOWNS
## EQUALITIES
X + Y = 20
## END EQUALITIES
## INEQUALITIES
X + 2 * Y > 10
## END INEQUALITIES
## PROFIT
X + Y
## END PROFIT
以下R代码提供了线性编程问题的解决方案:
require(LIM)
model= Setup("linprog.lim")
model.solved= Linp(model, ispos=F, verbose=T)
model.solved
输出:
$residualNorm
[1] 3.552714e-15
$solutionNorm
[1] 20
$X
X Y
[1,] 20 0
答案 3 :(得分:0)
这是另一种使用Rglpk库的方法,它可以读入并解决R中的GNU MathProg脚本问题:
# in case CRAN install does not work
install.packages("Rglpk", repos="http://cran.us.r-project.org")
library(Rglpk)
## read file
x= Rglpk_read_file("mathprog1.mod", type = "MathProg", verbose=T)
## optimize
Rglpk_solve_LP(obj= x$objective,
mat= x$constraints[[1]],
dir= x$constraints[[2]],
rhs= x$constraints[[3]],
bounds= x$bounds,
types= x$types,
max= x$maximum)
档案mathprog1.mod
:
# Define Variables
var x;
var y;
# Define Constraints
s.t. A: x + y = 20;
s.t. B: x + 2*y >= 10;
# Define Objective
maximize z: x + y;
# Solve
solve;
end;
R控制台输出:
# $optimum
# [1] 20
# $solution
# [1] 0 20
# $status
# [1] 0