แก้ระบบสมการเชิงเส้น


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

@ ใช่ใช่นั่นเป็นสิ่งที่ดี
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

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 อักขระ

ฉันรู้ว่ามันไม่ตรงกับข้อกำหนด (แก้ไข) แต่ก็ดีเกินไปที่จะไม่โพสต์:

สัญลักษณ์ "โดมิโน" (การแบ่ง÷ภายในสี่เหลี่ยม) ดำเนินการหารเมทริกซ์ดังนั้นจึงสามารถแก้ปัญหาระบบสมการเชิงเส้นใด ๆ คุณต้องใส่มันระหว่างเวกเตอร์เทอมคงที่กับเมทริกซ์กับเทอมอื่น:

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

(ถ้าคุณต้องการที่จะลองบน TryApl คือ)


4

Javascript ( 284 181) - วิธีกำจัด Gauss

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

แทนการใช้งานl=A.length;for(i=0;i<l;i++) for(i=0;i<l=A.length;i++)
Victor Stafusa

แทนการใช้งานfor(i=l-1;i>=0;i--) for(i=l;--i;)
Victor Stafusa

นอกจากนี้คุณยังสามารถย้าย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()เป็น typecast ไม่ใช่ฟังก์ชั่น ( import types; isinstance(matrix, types.FunctionType)ให้ใช้False) นอกจากนี้~และ*มีผู้ประกอบการ , ฟังก์ชั่นไม่ได้


ฉันได้อัปเดตกฎแล้ว รหัสจะต้องจัดการกับจำนวนสมการที่แตกต่างกันและตอนนี้คุณไม่สามารถใช้ฟังก์ชันเมทริกซ์ได้
qwr

3

Java - 522 434 228 213 ตัวอักษร

แก้ไขโดยการตรวจสอบจำนวนเต็ม n-tuples ทั้งหมดที่เป็นไปได้อย่างเป็นระบบโดยการคูณโดยตรงจนกว่าจะพบว่าใช้ได้

ฟังก์ชั่นใช้เมทริกซ์ยิ่ง, 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;}}}

โปรแกรมสำหรับการทดสอบ (ค่อนข้าง ungolfed):

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 

ฉันโกนตัวละครหลายตัวโดยทำตามคำแนะนำของวิกเตอร์เกี่ยวกับลูปและ "สาธารณะ" โดยเก็บ 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

@Victor ขอบคุณฉันได้เปลี่ยนแปลงสิ่งเหล่านี้และอื่น ๆ
Wally

while(true)สามารถเปลี่ยนเป็นfor(;;)
user12205

@ace ขอบคุณ - เปลี่ยนสิ่งนั้นและอีกสองสิ่งและโกน 15 ตัวอักษร
Wally

1

JavaScript (ES6),  152  151 ไบต์

การดำเนินการตามกฎของ Cramer

(m)(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))

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.