實驗一 直接法解線性方程組(android)

許佳佳233發表於2016-04-14

一、實驗目的

掌握Guass列選主消去法,三角分解法解線性方程。


二、實驗內容

分別寫出Guass列選主元消去法,三角分解法的演算法,編寫程式上機除錯出結果,要求所程式設計序適用於任何線性方程組問題,即能解決這一類問題,而不是某一個問題。

實驗中以下列資料驗證程式的正確性

1、Guass列選主元消去法

[2.5 2.3 -5.1][x1]  [3.7]

[5.3 9.6  1.5][x2]=[3.8]

[8.1 1.7 -4.3][x3]  [5.5]


2、Doolittle三角分解法

[ 2  10 0    -3 ]

[-3  -4 -12 13]

[ 1  2   3    -4 ]

[ 4  14 9   -13]


android效果:(原始碼附在文章底部)

    


大致思路:

1、一共有5次實驗,採用比較方便的fragment,底部是5個button

2、每一個實驗中的分功能使用spinner進行選擇。

3、通過頂部的一個TextView來提示使用者輸入的內容。

4、讓使用者每次輸入矩陣中的一個值,方便儲存。


對fragment有興趣的讀者可以看一下筆者的另外幾篇部落格:

android 自定義控制元件(底部icon點選效果)

android viewpager+fragment做主介面(超容易理解的demo!)

android Fragment與Activity互動,互相發資料(附圖詳解)



主要的運算邏輯就在OneFragment中處理了,此處就僅貼上OneFragment的程式碼。

OneFragment:

package com.example.double2.numericcalculationtest;

import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.text.DecimalFormat;

/**
 * 專案名稱:NumericCalculationTest
 * 建立人:Double2號
 * 建立時間:2016/4/13 21:41
 * 修改備註:
 */
public class OneFragment extends Fragment {
    private View views;
    private TextView tvGuidance;
    private Button btnInPut;
    private EditText etInput;
    private Button btnClear;
    private TextView tvProgress;
    private TextView tvResult;
    private Spinner spChose;
    private final String[] spinnerChose = {"Guass消去法", "Doolittle分解法"};
    private Double[][] aMatrix;//a矩陣
    private Double[] bMatrix;//b矩陣
    private int matrixSize;//矩陣大小
    private int linePosition;//行座標
    private int listPosition;//列座標
    private String progressShow;//用來展示過程
    private String resultShow;//用來展示結果
    private DecimalFormat mDecimalFormat = new DecimalFormat("0.00");//保留兩位小數


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        views = inflater.inflate(R.layout.act_one, null);
        initView();
        return views;
    }

    private void initView() {
        tvGuidance = (TextView) views.findViewById(R.id.tv_one_guidance);
        btnInPut = (Button) views.findViewById(R.id.btn_input);
        etInput = (EditText) views.findViewById(R.id.et_input);
        btnClear = (Button) views.findViewById(R.id.btn_clear);
        tvProgress = (TextView) views.findViewById(R.id.tv_one_progress);
        tvResult = (TextView) views.findViewById(R.id.tv_one_result);
        spChose = (Spinner) views.findViewById(R.id.sp_one_chose);

        tvGuidance.setText(R.string.input_size);
        spChose.setAdapter(new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, spinnerChose));

        btnInPut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                caculating();
            }
        });
        btnClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                clearData();
            }
        });
    }

    private void caculating() {
        //獲取到EditText中的String
        //如果為空就提示使用者並且直接返回
        String textInput = etInput.getText().toString();
        etInput.setText("");
        if (textInput.equals("")) {
            Toast.makeText(getActivity(), R.string.not_input_null, Toast.LENGTH_SHORT).show();
            return;
        }
        Log.d("xujiajia", spChose.getSelectedItemPosition() + "");
        //判斷為GUASS消元法還是Doolittle分解法
        if (spChose.getSelectedItemPosition() == 0) {
            GuassCaculation(textInput);
        } else {
            DoolittleCaculation(textInput);
        }
    }

    private void DoolittleCaculation(String textInput) {
        String textGuidance = tvGuidance.getText().toString();
        //需要輸入矩陣大小或者輸入矩陣中的值
        Log.d("xujiajia", textGuidance);
        //通過提示的TextView的text來判斷進行到哪一步
        if (textGuidance.equals(getString(R.string.input_size))) {
            matrixSize = Integer.parseInt(textInput);
            Log.d("xujiajia", matrixSize + "");
            aMatrix = new Double[matrixSize][matrixSize];
            progressShow = "a矩陣的大小被定義為 " + matrixSize + "如下\n" + "[ ";
            tvProgress.setText(progressShow);
            tvGuidance.setText("請依次輸入a矩陣中的值");
            linePosition = 0;
            listPosition = 0;
        } else {
            aMatrix[listPosition][linePosition] = Double.parseDouble(textInput);
            linePosition++;
            progressShow += textInput + " ";
            if (linePosition == matrixSize) {
                progressShow += "]\n";
                if (listPosition != matrixSize - 1)//如果不為最後一行就加前中括號
                    progressShow += "[ ";
                linePosition = 0;
                listPosition++;
            }
            tvProgress.setText(progressShow);
            if (listPosition == matrixSize) {
                //如果列座標與matrixSize相等,說明已經輸入完畢,進行運算
                for (int i = 1; i < matrixSize; i++) {
                    aMatrix[i][0] /= aMatrix[0][0];
                    for (int j = 1; j < matrixSize; j++) {
                        if (i > j) {
                            for (int k = 0; k < j; k++) {
                                aMatrix[i][j] -= aMatrix[k][j] * aMatrix[i][k];
                            }
                            aMatrix[i][j] /= aMatrix[j][j];
                        } else if (i <= j) {
                            for (int k = 0; k < i; k++)
                                aMatrix[i][j] -= aMatrix[k][j] * aMatrix[i][k];
                        }

                    }
                }

                //運算完畢,建立L矩陣和U矩陣,賦值並顯示
                Double[][] lMatrix = new Double[matrixSize][matrixSize];
                Double[][] uMatrix = new Double[matrixSize][matrixSize];
                for (int i = 0; i < matrixSize; i++) {
                    for (int j = 0; j < matrixSize; j++)
                        if (i == j) {
                            lMatrix[i][j] = 1.0;
                        } else if (i < j) {
                            lMatrix[i][j] = 0.0;
                        } else if (i > j) {
                            lMatrix[i][j] = aMatrix[i][j];
                        }
                }

                for (int i = 0; i < matrixSize; i++) {
                    for (int j = 0; j < matrixSize; j++)
                        if (i <= j) {
                            uMatrix[i][j] = aMatrix[i][j];
                        } else if (i > j) {
                            uMatrix[i][j] = 0.0;
                        }
                }

                resultShow = "最後算出的L如下\n";
                for (int i = 0; i < matrixSize; i++) {
                    resultShow += "[ ";
                    for (int j = 0; j < matrixSize; j++) {
                        resultShow += mDecimalFormat.format(lMatrix[i][j]) + " ";//保留兩位小數輸出
                    }
                    resultShow += "]\n";
                }

                resultShow += "最後算出的U如下\n";
                for (int i = 0; i < matrixSize; i++) {
                    resultShow += "[ ";
                    for (int j = 0; j < matrixSize; j++) {
                        resultShow += mDecimalFormat.format(uMatrix[i][j]) + " ";//保留兩位小數輸出
                    }
                    resultShow += "]\n";
                }

                tvResult.setText(resultShow);
                btnInPut.setClickable(false);//運算結束時,禁止使用者點選輸入,必須點選清空
            }
        }
    }

    private void GuassCaculation(String textInput) {
        String textGuidance = tvGuidance.getText().toString();
        //需要輸入矩陣大小或者輸入矩陣中的值
        Log.d("xujiajia", textGuidance);
        if (textGuidance.equals(getString(R.string.input_size))) {
            matrixSize = Integer.parseInt(textInput);
            aMatrix = new Double[matrixSize][matrixSize];
            progressShow = "a矩陣的大小被定義為 " + matrixSize + "如下\n" + "[ ";
            tvProgress.setText(progressShow);
            tvGuidance.setText(R.string.input_a_number);
            linePosition = 0;
            listPosition = 0;
        } else if (textGuidance.equals(getString(R.string.input_a_number))) {
            aMatrix[listPosition][linePosition] = Double.parseDouble(textInput);
            linePosition++;
            progressShow += textInput + " ";
            if (linePosition == matrixSize) {
                progressShow += "]\n";
                if (listPosition != matrixSize - 1)//如果不為最後一行就加前中括號
                    progressShow += "[ ";
                linePosition = 0;
                listPosition++;
                if (listPosition == matrixSize) {
                    //如果列座標與size相等,說明a已經輸入完畢,輸入b
                    tvGuidance.setText(R.string.input_b_number);
                    bMatrix = new Double[matrixSize];
                    progressShow += "b矩陣如下\n[ ";
                }
            }
            tvProgress.setText(progressShow);
        } else if (textGuidance.equals(getString(R.string.input_b_number))) {
            bMatrix[linePosition] = Double.parseDouble(textInput);
            linePosition++;
            progressShow += textInput + " ";
            if (linePosition == matrixSize) {
                progressShow += "]\n";
            }
            tvProgress.setText(progressShow);

            if (linePosition == matrixSize) {
                caculateAB();
            }
        }
    }

    private void caculateAB() {
        //ab矩陣都輸入完畢,接下來進入計算
        for (int i = 0; i < matrixSize - 1; i++) {
            linePosition = 0;
            listPosition = 0;
            Double maxNum = aMatrix[i][0];
            for (int j = i; j < matrixSize; j++) {
                if (Math.abs(aMatrix[j][i]) > Math.abs(maxNum))//標記最大的數以及所在行
                {
                    maxNum = aMatrix[j][i];
                    listPosition = j;
                }
            }
            //交換行
            if (listPosition != i) {
                Double[] aTemp = aMatrix[listPosition];
                aMatrix[listPosition] = aMatrix[i];
                aMatrix[i] = aTemp;

                Double bTemp = bMatrix[listPosition];
                bMatrix[listPosition] = bMatrix[i];
                bMatrix[i] = bTemp;
            }
            //消元
            for (int j = i + 1; j < matrixSize; j++) {
                Double factor = aMatrix[j][i] / maxNum;
                //a中迴圈計算
                for (int k = 0; k < matrixSize; k++)
                    aMatrix[j][k] -= aMatrix[i][k] * factor;
                //b中迴圈計算
                bMatrix[j] -= bMatrix[i] * factor;
            }

        }

        //建立X並且計算
        resultShow = "最後算出的x如下\n[ ";
        Double[] xMatrix = new Double[matrixSize];
        for (int i = matrixSize - 1; i >= 0; i--) {
            Double number = bMatrix[i];
            for (int j = matrixSize - 1; j > i; j--)
                number -= aMatrix[i][j] * xMatrix[j];
            number /= aMatrix[i][i];
            xMatrix[i] = number;
        }
        for (int i = 0; i < matrixSize; i++)
            resultShow += mDecimalFormat.format(xMatrix[i]) + " ";//保留兩位小數輸出
        resultShow += "]\n";
        tvResult.setText(resultShow);
        btnInPut.setClickable(false);//運算結束時,禁止使用者點選輸入,必須點選清空
    }

    //清空所有資料
    private void clearData() {
        tvGuidance.setText("請輸入矩陣的大小");
        progressShow = "";
        resultShow = "";
        tvProgress.setText("");
        tvResult.setText("");
        listPosition = 0;
        linePosition = 0;
        aMatrix = null;
        bMatrix = null;
        btnInPut.setClickable(true);
    }
}

原始碼地址:http://download.csdn.net/detail/double2hao/9491269



相關文章