一、实验目的
掌握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); } }