實驗五 迭代法解線性方程組與非線性方程(android)

許佳佳233發表於2016-05-25

實驗一部落格地址:http://blog.csdn.net/double2hao/article/details/51152843

實驗二部落格地址:http://blog.csdn.net/double2hao/article/details/51217356

實驗三部落格地址:http://blog.csdn.net/double2hao/article/details/51344145

實驗四部落格地址:http://blog.csdn.net/double2hao/article/details/51372731


【實驗內容】


分別寫出高斯-賽德爾迭代法與牛頓迭代法的演算法,編寫程式上機除錯出結果,要求所程式設計序適用於任何一個方程的求根,即能解決這一類問題,而不是某一個問題。


1、高斯-賽德爾迭代法求解線性方程組

[ 7  2   1 -2][x1]  [ 4]

[ 9 15  3 -2][x2]  [ 7]

[-2 -2 11  5][x3]=[-1]

[1  3  2  13][x4]  [ 0]


2、用牛頓迭代法求方程x^3-x-1=0的近似根,精確度<=0.00001,牛頓法的初始值為1.



效果:(原始碼在文章結尾)

 


主要工作:

1、新增了FiveFragment的xml介面,直接採用文字讀取的方式讀取矩陣。(使用java的split)

輸入的時候比較方便,可以直接複製。但是輸入內容如果有錯誤就會導致程式崩潰,比較難控制。



2、掌握理解高斯-賽德爾迭代法和牛頓迭代法



主要邏輯程式碼

FiveFragment:

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 FiveFragment extends Fragment {

    private View views;
    private Spinner spChose;
    private final String[] spinnerChose = {"高斯-賽德爾迭代法", "牛頓法"};
    private EditText etInputN;
    private EditText etInputMatrix;
    private Button btnCalculate;
    private Button btnClear;
    private TextView tvResult;
    private String resultShow;//用來展示結果
    private DecimalFormat mDecimalFormat = new DecimalFormat("0.000000");//保留六位小數

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

    private void initView() {
        spChose = (Spinner) views.findViewById(R.id.sp_five_chose);
        etInputN = (EditText) views.findViewById(R.id.et_input_n);
        etInputMatrix = (EditText) views.findViewById(R.id.et_input_matrix);
        btnCalculate = (Button) views.findViewById(R.id.btn_five_calculate);
        btnClear = (Button) views.findViewById(R.id.btn_five_clear);
        tvResult = (TextView) views.findViewById(R.id.tv_five_result);

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

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

    private void calculating() {
        //獲取到EditText中的String
        String textInputN = etInputN.getText().toString();
        String textInputMatrix = etInputMatrix.getText().toString();

        Log.d("xujiajia", spChose.getSelectedItemPosition() + "");
        //判斷為高斯-賽德爾迭代法還是牛頓法
        if (spChose.getSelectedItemPosition() == 0) {
            //如果為空就提示使用者並且直接返回
            if (textInputN.equals("") || textInputMatrix.equals("")) {
                Toast.makeText(getActivity(), R.string.not_input_null, Toast.LENGTH_SHORT).show();
                return;
            } else {
                G_sCalculation(textInputN, textInputMatrix);
            }
        } else {
            NewtonCalculation();
            etInputMatrix.setText("牛頓法計算的為x^3-x-1=0的近似根\n精度<=0.00001,牛頓法的初始值為1。");
        }
    }


    private void G_sCalculation(String textInputN, String textInputMatrix) {
        int n = Integer.parseInt(textInputN);
        final int iSize = 5;//迭代次數
        double[][] matrix = new double[n][n + 1];//用來儲存矩陣
        double[][] result = new double[iSize + 1][n];//result用來儲存迭代的數,規定迭代5次,第一組都為0

        String[] line = textInputMatrix.split("\n");
        Log.d("xujiajia5", line[0] + "\n");
        Log.d("xujiajia5", line[1] + "\n");
        for (int i = 0; i < n; i++) {
            String[] num = line[i].split(" ");
            for (int j = 0; j < n + 1; j++) {
                Log.d("xujiajia5", num[j]);
                matrix[i][j] = Double.parseDouble(num[j]);
            }
            result[0][i] = 0;//初始向量設定為0
        }

        for (int i = 1; i < iSize + 1; i++) {
            for (int j = 0; j < n; j++) {
                result[i][j] = matrix[j][n];
                for (int k = 0; k < n; k++)
                    if (k < j) {
                        result[i][j] -= matrix[j][k] * result[i][k];
                        Log.d("xujiajia555", matrix[j][k] + "");
                        Log.d("xujiajia555", result[i][k] + "");
                    } else if (k > j) {
                        result[i][j] -= matrix[j][k] * result[i - 1][k];
                    }
                result[i][j] /= matrix[j][j];
            }
        }

        resultShow = "迭代次數為 " + iSize + "\n";
        resultShow += "最終的結果為:\n";
        for (int i = 0; i < n; i++)
            resultShow += mDecimalFormat.format(result[iSize][i]) + "\n";
        tvResult.setText(resultShow);

    }

    private void NewtonCalculation() {
        double[] k = new double[3];
        k[0] = 0.5;
        k[1] = 1;

        while (Math.abs(k[1] - k[0]) >= 0.00001) {
            k[2] = k[1] - f(k[1]) / (f(k[1]) - f(k[0])) * (k[1] - k[0]);
            k[0] = k[1];
            k[1] = k[2];
        }

        resultShow = "牛頓法的結果為:\n";
        resultShow += k[1] + "";
        tvResult.setText(resultShow);
    }

    private void clearData() {
        etInputN.setText("");
        etInputMatrix.setText("");
        tvResult.setText("");
        resultShow = "";
    }

    double f(double x) {
        return (Math.pow(x, 3) - x - 1);
    }

}


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


相關文章