我正在尝试解决以下方程组:
x1 + x2 + x3 = 1
0.5 * x1 + 0.75 * x2 + 0.25 * x3 = 0.25
我首先从均匀分布中随机选择 $x 3 美元。然后我更新我的方程组以求解剩余的 x1 和 x2。但是,我想确保 x1 和 x2 也介于 0 和 1 之间。目前,求解上述方程组示例会导致负 x1 和大于 1 的 x2。有没有办法以某种方式合并此约束?
library(matlib)
set.seed(3)
x3 <- runif(1, 0.01, 0.99)
A <- matrix(c(1, 2/4, 1, 3/4), 2, 2)
b <- c(1 - x3, 0.25 - 1/4 * x3)
showEqn(A, b)
> Solve(A, b)
x1 = -0.34936139
x2 = 1.1746807
两个线性方程的解是两个平面的交点,即一条线。那么,满足 x1 和 x2 约束的行上的任何值都是有效的。在这种情况下,x2 = -x1/2
和x3 = 1 - x1/2
,因此唯一的解决方案是(x1, x2, x3) = (0, 0, 1)
.
如果你想要符号解决方案,那么R可能不是正确的选择。而是使用像Mathematica这样的CAS或约束满足器来确定可行性区域:
Solve[x1 + x2 + x3 == 1 && 0.5 x1 + 0.75 x2 + 0.25 x 3 == 0.25 && 0 <= x1 <= 1 && 0 <= x2 <= 1, {x1,x2,x3}, Reals]
输出
{{x1 -> 0, x2 -> 0, x3 -> 1.}}
如果您的约束没有唯一的解决方案,例如-1 <= x2 <= 1
,您将获得类似
{{x1 -> ConditionalExpression[1. - 1. x2 - 1. (1. + x2), -0.5 <= x2 <= 0],
x3 -> ConditionalExpression[1. + x2, -0.5 <= x2 <= 0]}}
相反,如果您想要一个数值解,那么 LP 求解器非常适合此任务。由于您没有最大化或最小化任何东西,因此任何满足约束的解决方案都将起作用。在这里,我"最大化"零目标函数以获得任何解决方案。
library(lpSolve)
# x1 + x2 + x3 = 1
# 0.5 x1 + 0.75 x2 + 0.25 x3 = 0.25
# x1 >= 0
# x1 <= 1
# x2 >= 0
# x2 <= 1
f.obj <- c(0, 0, 0)
f.con <- matrix(c(1, 1, 1, 0.5, 0.75, 0.25, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0), nrow=6, byrow=TRUE)
f.dir <- c("=", "=", ">=", "<=", ">=", "<=")
f.rhs <- c(1, 0.25, 0, 1, 0, 1)
lp ("max", f.obj, f.con, f.dir, f.rhs)$solution
输出
[1] 0 0 1
对于剩余两个变量的两个方程,如果方程是独立的,则结果是唯一的,因此您无法约束结果。
您可以做的是以解析方式求解方程,并找到解集中x1
、x2
和x3
介于 0 和 1 之间的位置。
否则,您可以保留您的方法并在最后检查x1
和x2
是否介于 0 和 1 之间。如果没有,您可以重复该操作(例如,您将代码放入while(TRUE)
循环中,并在找到合适的解决方案时break
(。但是,如果这样做,则应设置迭代限制,否则,如果所需范围内不存在解决方案,则代码可能会无限期运行。