読者です 読者をやめる 読者になる 読者になる

丸三角四角

IT業界にしがみつく新人SEが立派なプログラマになろうともがく奮闘記

【Java】連立方程式を解く_Ver1

今回は連立方程式の解を求める問題です。

コード更新しています。解説等はこのままこの記事で解説していますので、解説等読んだ後はVer2のコードを参照してください。

dadainu.hateblo.jp

連立方程式は手で書きながらやる分には全然簡単なのですが、いざプログラムでやろうとすると、、、?とりあえず、xとyをイコールで求められる式まで落とし込むことにしました。

1.ax + by = c
       by = c - ax
        y = (c - ax) / b
2.dx + ey               = f
  dx + e((c-ax) / b)    = f
  dx + ce / b - aex / b = f
             (bd - ae)x = f - ce /b
                      x = (bf - ce) / (bd - ae)

 上記の式を利用して解を求めます。

import static java.lang.System.out;
import static java.lang.Double.parseDouble;
import java.io.File;
import java.util.Scanner;

public class SimultaneousEquation {

    public static void main(String[] args) {
        new SimultaneousEquation().simul();
    }

    public void simul() {
        try (Scanner scan = new Scanner(System.in)) {
            simulEqua(scan);
        } catch (Exception e) {
        }
    }

    public void simul(String inDataPath) {
        try (Scanner scan = new Scanner(new File(inDataPath))) {
            simulEqua(scan);
        } catch (Exception e) {
        }
    }

    public void simulEqua(Scanner scan) {
        String inData;
        while ((inData = scan.nextLine()) != null || !"".equals(inData)) {
            String[] abcdefList = inData.split(" ");
            double[] in = new double[6];
            for (int i = 0; i < 6; i++) {
                in[i] = parseDouble(abcdefList[i]);
            }
            double[] xy = getXY(in);
            out.printf("%4.3f %4.3f\n", xy[0], xy[1]);
        }
    }

    public double[] getXY(double[] in) {
        double[] xy = new double[2];
        xy[0] = (in[1] * in[5] - in[2] * in[4]) / (in[1] * in[3] - in[0] * in[4]);
        xy[0] = judge(xy[0]);
        xy[1] = (in[2] - in[0] * xy[0]) / in[1];
        xy[1] = judge(xy[1]);
        return xy;
    }

    public double judge(double num) {
        return (num == -0.0) ? 0.0 : num;
    }
}

getXYというメソッドで式を利用しています。久しぶりに数式をいじったので、解くのにかなり時間がかかりました。配列を使用しているため、どこがaでどこがbかが分かりづらいですが、一応abcdefの順番に入れています。より分かりやすく記載できる方法があればコメントお願いいたします。

テストドライバは以下になります。

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import volume0.BaseTest;

public class SimultaneousEquationTest extends BaseTest {

    private SimultaneousEquation se;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        se = new SimultaneousEquation();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void testSimul0001() {
        try {
            se.simul("./data/volume0_0004/0001/in.txt");
            outList = outContent.toString().split("\n");
            assertOut(outList, "./data/volume0_0004/0001/out.txt");
        } catch (Exception e) {
            printErr(e);
        }
    }

    @Test
    public void testSimul0002() {
        try {
            se.simul("./data/volume0_0004/0002/in.txt");
            outList = outContent.toString().split("\n");
            assertOut(outList, "./data/volume0_0004/0002/out.txt");
        } catch (Exception e) {
            printErr(e);
        }
    }

}

 テストドライバの「in.txt」「out.txt」は以下になります。

0001/in.txt
1 2 3 4 5 6
2 -1 -2 -1 -1 -5
0001/out.txt
-1.000 2.000
1.000 4.000
0002/in.txt
2 -1 -3 1 -1 -3
2 -1 -3 -9 9 27
0002/out.txt
0.000 3.000
0.000 3.000

 

今回の問題は、以下にあります。

連立方程式 | Aizu Online Judge

アルゴリスムで困った時は、以下の本を参考にしてます。Javaに置き換えるのが少々難解ですが、、、

テストドライバで継承しているクラスは以下の記事に記載しています。参考にしてみてください。

dadainu.hateblo.jp