给定一些lineqr(in)相等,将它转换为系数矩阵形式的简单算法是什么?
因此,例如给定((3(x+5)/(2(y-1)))<4
(作为树,所以运算符顺序是明确定义的)如何有效地将其转换为3x-8y<-23
或类似的东西?
任何暗示使用什么算法?
答案 0 :(得分:1)
让我们看看你将如何手动完成这项工作
((3(x+5)/(2(y-1)))<4
3 (x+ 5) < ( 2 ( y - 1) ) * 4 Multiply by bottom note 1
3 x + 5 < 8 y - 8 Expand
3 x - 8 y + 5 < -8 Take 8 y across
3 x - 8 y < -13 Take 5 across
这仅在2 (y-1)
为正时才有效,否则您需要将小于号更改为大于号。
您可以使用两种基本策略。
将每个单独的节点转换为系数矩阵,然后对这些矩阵执行数学运算,以获得最终答案。
简化表达式,然后将其转换为系数矩阵。
让我们看一个没有分裂的表达,这使事情变得复杂。
(3(x+5))*(2(y-1))<4
对于常数3,写入或系数矩阵为[3],对于x,[2 y,0]为2,写入[x,0]。将每个叶节点转换为系数给出
([3]*([x,0]+[5]))*([2]*([y,0]-[1]))<[4]
处理树
([3]*[x,5])*([2]*[y,-1])<[4]
[3 x,15]*[2 y,-2] < [4]
[6 x y,-6 x, 30 y, -30] < [4]
[6 x y,-6 x, 30 y, -34] < [0]
要实际实现这一点,您需要一个系数矩阵类,它具有执行每个基本操作的方法。假设我们知道答案都是x和y中的多项式。我们的课可能类似
class Polynomial {
double data[][];
int degX,degY;
// Constructor from a constant
Polynomial(double val) {
data = new double[1][1];
data[0][0]=val;
degX = degY = 0;
}
// Constructor from a variable
Polynomial(String name) {
if(name == "x") {
data = new double[2][1];
data[1][0]=1;
degX=1; degY=0;
} else if( name=="y") [
data = new double[1][2];
data[0][1]=1;
degX=1; degY=0;
}
}
// Add two polynomials
Polynomial add(Polynomial A,Polynomial B) {
int dX = max(A.degX,B.degX);
int dY = max(A.degY,B.degY);
double coeffs[][] = new double[dx+1][dy+1];
for(int i=0;i<A.degX;++i)
for(int j=0;j<A.degY;++j)
coeffs[i][j] += A.data[i][j];
for(int i=0;i<B.degX;++i)
for(int j=0;j<B.degY;++j)
coeffs[i][j] += B.data[i][j];
return new Polynomial(coeffs,degX,degY);
}
// Multiply two polynomials
Polynomial mul(Polynomial A,Polynomial B) {
int dx = A.degX * B.degX;
int dy = A.degY * B.degY;
double coeffs[][] = new double[dx+1][dy+1];
for(int i=0;i<A.degX;++i)
for(int j=0;j<A.degY;++j)
for(int k=0;k<B.degX;++k)
for(int l=0;l<A.degY;++l)
coeffs[i+k][j+l] = coeffs[i][j] * coeffs[k][l];
return new Polynomial(coeffs,degX,degY);
}
}
然后,您需要深度优先递归树遍历例程
Polynomial walk(Node n) {
if( isConstant(n) )
return new Polynomial( n.value );
if( isIdentifier(n) )
return new Polynomial( n.name );
if( node.op = "+" )
return Polynomial.add( walk(n.left), walk(n.right) );
if( node.op = "*" )
return Polynomial.mul( walk(n.left), walk(n.right) );
}
分部使事情变得更加困难。
答案 1 :(得分:0)
您正在寻找能够进行代数简化的东西。有很多计算机代数系统(CAS),我建议SymPy
或Sage
(都在Python中)。
请注意,您提供的示例((3(x+5)/(2(y-1)))<4
不是线性不等式,因此CAS无法将其“转换为3x-8y<-23
或等效的内容。”