解决线性方程组


12

编写程序,以解决尽可能短的一系列线性方程。它必须解决任意数量的方程式问题。他们可以输入,但是您喜欢,增广矩阵的系数可能是最简单的。该程序不必处理非整数系数或解决方案。不会对任何退化或无效的案例进行测试。程序必须输出每个变量或精简行梯形表格的值。

不允许方程求解库,矩阵函数或任何自动求解的方法。您可以使用数组或列表来模拟矩阵。

输入示例(或等效输入):

m={{2,1,-1,8},{-3,-1,2,-11},{-2,1,2,-3}}

这代表 2x+y-z=8, -3x-y+2z=-11, -2x+y+2z=-3

示例输出(或等效输出):

{2,3,-1}

这代表 x=2, y=3, z=-1


2
变量的系数和常数项可以在输入中分为两个数组吗?
user12205 2014年

@ace是的,那很好
qwr

1
你在退化的情况下到底在说什么?我想您指的是所有这些情况:1)输入格式错误;2)类似0x=00x=5;4)方程数与变量数不同的情况;5)类似的矛盾案例x+5y=7, x+5y=8;6)没有线性独立性的情况,例如x+3y=6, 2x+6y=12。我对吗?
Victor Stafusa 2014年

@Victor是的,任何含糊不清或无法解决的输入。
qwr 2014年

没有退化但病情恶化的情况又如何呢?(或者换句话说,需要进行哪种类型的旋转?)
Peter Taylor

Answers:


3

Python的169 166

实作

def s(a):
 if a:b=a[0];r=s([[x-1.*y*b[0]/r[0]for x,y in zip(b[1:],r[1:])]for r in a[1:]]);return[round((b[-1]-sum(x*y for x,y in zip(b[1:-1],r)))/b[0])]+r
 return[]

演示版

>>> arr=[[2, 1, -1, 8], [-3, -1, 2, -11], [-2, 1, 2, -3]]
>>> s(arr)
[2.0, 3.0, -1.0]

注意

如果您对浮点近似没问题,则可以删除圆形函数调用,然后进一步打高尔夫球至159个字符


9

APL,1个字符

我知道这不符合(修订)的要求,但是不能发布它太好了:

符号“ domino” ÷矩形内的除法)执行矩阵除法,因此它可以求解任何线性方程组。您只需要把它放在常数项向量和带有其他项的矩阵之间:

      8 ¯11 ¯3 ⌹ ⊃(2 1 ¯1)(¯3 ¯1 2)(¯2 1 2)
2 3 ¯1

(如果您想在TryApl上进行尝试,则为


4

Javascript(284181)- 高斯消除方法

function f(A){l=A.length;d=1;for(i=0;i+1;i+=d){v=A[i][i];for(k=0;k<l+1;k++)A[i][k]/=v;for(j=i+d;A[j];j+=d)for(k=0,w=A[j][i];k<l+1;k++)A[j][k]-=w*A[i][k];if(i==l-d)d=-1,i=l}return A}

测试

f([[2,1,-1,8],[-3,-1,2,-11],[-2,1,2,-3]]);

=> [[1,0,0,2],[0,1,0,3],[-0,-0,1,-1]]

返回的数组结合了单位矩阵和解。


您可以再保存几个字符。
MarcinJuraszek 2014年

代替l=A.length;for(i=0;i<l;i++)使用for(i=0;i<l=A.length;i++)
维克多·斯塔夫萨

代替for(i=l-1;i>=0;i--)使用for(i=l;--i;)
维克多·斯塔夫萨

您也可以w=A[j][i]进入for()并跳来跳去{}
MarcinJuraszek 2014年

谢谢大家,我成功地将前进和后退步骤合并为一个步骤,节省了一百个字符,您的一些提示不再有效。(@MarcinJuraszek小费除外)
Michael M.

3

规则更改后,此答案不再适合该问题,因为它使用矩阵函数。*

贤者,32

~matrix(input())*vector(input())

输入样例:

[[2, 1, -1], [-3, -1, 2], [-2, 1, 2]]
[8, -11, -3]

样本输出:

(2, 3, -1)

*可以说matrix()是一个类型转换,而不是一个函数(运行import types; isinstance(matrix, types.FunctionType)给出False)。另外,~*运算符,不是函数。


我已经更新了规则。该代码必须处理不同数量的方程式,现在您不能使用矩阵函数。
qwr 2014年

3

爪哇- 522 434 228 213个字符

通过直接乘法系统地检查所有可能的整数n元组,直到找到一个可行的整数,然后进行求解。

函数将增强矩阵A,试验解向量x和维度n作为输入-输出解向量x。请注意,向量x实际上比维度大一,以帮助逐步解决可能的问题。(如果我将变量A,x,n,j,k,s声明为实例变量,则该函数将短31个字符-共计182个字符,但这感觉像是将规则弯曲得太远了。)

int[]Z(int[][]A,int[]x,int n){int j,k,s;for(;;){for(j=0;j<n;j++){for(k=s=0;k<n;s+=A[j][k]*x[k++]);if(s!=A[j][n])j+=n;}if(j==n)return x;for(j=0;j<=n;j++)if(x[j]!=x[n]||j==n){x[j]++;for(k=0;k<j;x[k++]=-x[n]);j=n;}}}

测试程序(有点不实用):

import java.util.*;
class MatrixSolver{
    public MatrixSolver() {
        Scanner p=new Scanner(System.in); //initialize everything from stdin
        int j,k,n=p.nextInt(),A[][]=new int[n][n+1],x[]=new int[n+1];
        for(j=0;j<n;j++)for(k=0;k<=n;A[j][k++]=p.nextInt());
        x=Z(A,x,n); //call the magic function
        for(j=0;j<n;j++) System.out.print(x[j]+" "); //print the output
    }
    public static void main(String[]args){
        new MatrixSolver();
    } 

    int[]Z(int[][]A,int[]x,int n){
        int j,k,s;
        for(;;){
            for(j=0;j<n;j++){ //multiply each row of matrix by trial solution and check to see if it is correct
                for(k=s=0;k<n;s+=A[j][k]*x[k++]);
                if(s!=A[j][n])j+=n;
            }
            if(j==n)return x; //if it is correct return the trial solution
            for(j=0;j<=n;j++)if(x[j]!=x[n]||j==n){//calculate the next trial solution
                x[j]++;
                for(k=0;k<j;x[k++]=-x[n]);
                j=n;
            }
        }
    }
}

程序将来自stdin的输入作为空格分隔的整数,如下所示:首先,问题的维数,其次,是逐行扩展矩阵的条目。

样品运行:

$java -jar MatrixSolver.jar
3 2 1 -1 8 -3 -1 2 -11 -2 1 2 -3
2 3 -1 

我遵循Victor关于循环和“公共”的建议,剃掉了几个角色,将RHS而不是单独存储在增强矩阵中,并在我的试用解决方案中添加了一个额外的条目以简化每个新试用解决方案的生成。OP还表示,一个功能就足够了-无需计算整个程序。


while(true){f=0;for(j=0;j<n;j++)可以替换为while(true){for(f=j=0;j<n;j++)。此外,您的课程不需要公开。主体中只有一条指令的For循环不需要花括号。
维克多·斯塔夫萨

我认为for(j=0;j<n;j++){for(k=0;k<n;k++){A[j][k]=p.nextInt();}b[j]=p.nextInt();}可以用for(j=0;j<n;b[j++]=p.nextInt())for(k=0;k<n;)A[j][k++]=p.nextInt();
Victor Stafusa

@Victor谢谢,我进行了其他更改。
沃利

while(true)可以更改为for(;;)
2014年

@ace谢谢-更改了此内容以及其他几处内容,并削减了15个字符。
沃利

1

的JavaScript(ES6), 152个  151字节

克莱默规则的实施。

(m)(v)v

m=>v=>m.map((_,i)=>(D=m=>m+m?m.reduce((s,[v],i)=>s+(i&1?-v:v)*D(m.map(([,...r])=>r).filter(_=>i--)),0):1)(m.map((r,y)=>r.map((k,x)=>x-i?k:v[y])))/D(m))

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.