선형 방정식 시스템 풀기


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

@ace 예, 괜찮습니다
qwr

1
퇴화 사례에 의해 정확히 무엇을 말하고 있습니까? 나는 당신이 그 모든 경우를 언급하고 있다고 생각합니다 : 1) 잘못된 입력; 2) 0x=0또는 것 0x=5; 4) 방정식의 수가 변수의 수와 다른 경우; 5) 모순되는 경우 x+5y=7, x+5y=8; 6) 선형 독립성이없는 경우 x+3y=6, 2x+6y=12. 내가 맞아?
Victor Stafusa

@Victor 네, 모호성이 있거나 해결할 수없는 입력입니다.
qwr

퇴화되지는 않지만 상태가 좋지 않은 경우는 어떻습니까? (즉, 어떤 종류의 피벗이 필요합니까?)
Peter Taylor

답변:


3

파이썬 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]

노트

float 근사값에 문제가 없으면 round 함수 호출을 제거하고 159 자 까지 추가 골프를 수행 할 수 있습니다.


9

APL, 1 자

나는 그것이 (수정 된) 요구 사항에 맞지 않는다는 것을 알고 있지만 게시하지 않는 것이 좋습니다.

"domino"기호 ( ÷사각형 내부의 나눗셈 )는 행렬 나누기를 수행하므로 모든 선형 방정식 시스템을 해결할 수 있습니다. 상수 항 벡터와 다른 항을 가진 행렬 사이에 배치해야합니다.

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

(당신이 TryApl에 그것을 시도하려는 경우 입니다 )


4

자바 스크립트 ( 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 1

대신에 l=A.length;for(i=0;i<l;i++)사용 for(i=0;i<l=A.length;i++).
Victor Stafusa 1

대신에 for(i=l-1;i>=0;i--)사용 for(i=l;--i;).
Victor Stafusa 1

당신은 또한 이동할 수 w=A[j][i]for()건너 뛰 {}주변.
MarcinJuraszek

모두 감사합니다. 한 단계로 앞뒤로 단계를 병합하여 백자를 절약했으며 일부 팁은 더 이상 유효하지 않습니다. (@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). 또한 ~and *연산자 가 아니라 함수입니다.


규칙을 업데이트했습니다. 코드는 다른 수의 방정식을 처리해야하며 이제 행렬 함수를 사용할 수 없습니다.
qwr

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++). 또한 수업은 공개 할 필요가 없습니다. 본문에 하나의 명령 만있는 루프는 중괄호가 필요하지 않습니다.
Victor Stafusa

나는 그것을 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

@ 빅터 감사합니다, 나는 그와 다른, 변경했습니다.
Wally

while(true)다음으로 변경 될 수 있습니다for(;;)
user12205

@ 에이스 감사-그와 몇 가지 다른 것들을 변경하고 15자를 면도했습니다.
Wally

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.