《解方程》的观课报告
刘怀强
本节课田老师能够努力营造宽松、民主和谐的学习环境,引导学生积极参与学习过程。重视师生、生生间的互动交流,注重学生的想法。通过小组讨论、同桌合作交流学习方式,给学生提供自主的活动空间和交流的机会,引领学生通过自己的探索来获取知识,体现出主体性教学的课程新理念。教学过程有条理性,教学效果显著。我个人认为田老师执教的《解方程》一课有以下几个亮点。
1 、利用多媒体课件演示,灵活地处理和利用教材。通过多媒体的演示吸引学生的注意,激发学生的学习兴趣。
2、努力营造宽松和谐的课堂氛围,使学生在自主探究、合作交流中体验学习数学的乐趣。如:在具体指导学生解方程的过程中,田老师要求学生先独立思考,再在小组内讨论交流,接着展示小组合作探究的结果,请小组里的同学口述解方程的过程,同时教师用课件演示或教师根据学生的汇报板书。田老师利用小组交流合作的学习方式大胆地放手学生自主探究本课的教学重点,同时做到有的放矢,能很好归纳总结,这一点做得非常好。在此过程中田老师突出强调两点:其一是解方程的依据是什么;其二是注意解方程的格式。突出了这两点,为以后解稍复杂方程做准备。
3、课堂结构安排的非常合理。主要体现在以下两个几方面:1、教学环节的时间分配的很合理,并且讲与练时间搭配也很合理。2.教师活动与学生活动时间分配合理,田老师占用时间与学生活动时间刚好相等。并且学生的个人活动时间与学生集体活动时间的分配也很合理。
除了以上几点外,田老师执教的这节课还有值得我们学习的地方:
把抽象的解方程的过程用形象化的方式表现出来,使学生更好的理解解方程的过程是一个等式的恒等变形。并能站在“学生是学习的主人”和“教师是学习的组织者、引导者与合作者”的这一角度上,为学生创设学习此课的情境,通过直观演示,充分给学生提供小组交流的机会。在不断对孩子们进行潜移默化地渗透,促使绝大部分的学生都能灵活地运用此规律来解方程。从而,使田老师很顺利地就完成了本课的教学任务。注重学生良好学习习惯的培养;教师教学语言准确、严密;对学生的启发、点拨恰到好处,与学生的交流亲切自然。
第二篇:直接法解线性方程组报告
全选主元算法:
1. 输入方程组维数n,矩阵a,右端项b和控制精度eps;
初始化用于标记方程组解顺序的数组flag,flag[i]:=i(i=0:N-1)
2. 对于r=0:n-2
(1) |a(p,q)|=max|a(x,y)|(r<=x<n,y<=r<n) %全选主元
(2) 如果|a(p,q)|<eps则停止 %控制小主元
(3) 如果p=r,则转(4),否则 %换行
(4) 如果q=r,则转(5),否则
;flag(r) %换列
(5) a(r+1:n-1,r+1:n-1):=a(r+1:n-1,r+1:n-1)-a(r+1:n-1,r)*a(r,r+1:n-1)/a(r,r)
b(r+1:n-1)=b(r+1:n-1)-a(r+1:n-1,r)*b?/a(r,r) %按行消元
3. 如果|a(n-1,n-1)|<=eps则停止 %无解
4. b(n-1):=b(n-1)/a(n-1,n-1),
对于i=n-2:-1:1,b(i):=[b(i)-a(i,i+1:n-1)*b(i+1:n-1)]/a(i,i) %回带求解
5.输出解b(0:n-1)
Gauss全选主元解方程组的源程序及运行结果
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
class Matrix
{
public:
Matrix();
~Matrix();
void SetMatrix(const int n,const double esp1);//构造线性方程组相应的矩阵,n为方程的未知数数目,esp1为要求的精度
void Max(const int r);//全选主元
void ChangeRC(const int r);//根据主元变换矩阵的行或列
void Eliminate(const int r);//处理消元工作
void Result()const;//计算方程的解
void Calculate();
int GetRank()const;//返回矩阵的行数
double GetX(const i)const;//确定方程组的第i个解(1<=i<=N)
private:
//指针a和b分别用于存储方程组的未知数系数和方程"="右边的常数,esp存//储精度
double *a,*b,esp;
//指针flag用于记录方程组解的顺序
int *flag;
//以下的结构体用于在全选主元中记录最大主元的位置
struct coordinate
{
int row,column;
}location;
int N;//方程组未知数的数目
};
int main()
{
int n;
double esp1;
Matrix matrix;
do{
cout<<"请输入方阵的阶数:";
cin>>n;
if(n<0) n=0;//如何控制非法字符的输入?????????? }while(n==0);
do
{
cout<<"请输入计算精度:";
cin>>esp1;
if(esp1<0) esp1=0;//输入不合法的精度就把精度置0
}while(esp1==0);
cout<<"输入线性方程组的增广矩阵:\n";
matrix.SetMatrix(n,esp1);//设置矩阵内的数据
matrix.Calculate();//计算方程组的解
//输出方程组的解
cout<<"\n\n方程组的解如下:\n";
for(int i=1;i<=matrix.GetRank();++i)
cout<<"X["<<i<<"]:"<<matrix.GetX(i)<<endl;
return 0;
}
Matrix::Matrix()
{ //将Matrix类的数据成员初始化
a=NULL;
b=NULL;
flag=NULL;
location.row=0;
location.column=0;
esp=0;
N=0;
}
Matrix::~Matrix()
{ //释放指针a、b和flag指向的内存空间
delete[]a;
delete[]b;
delete[]flag;
}
void Matrix::SetMatrix(const int n,const double esp1)
{
N=n;
esp=esp1;
a=new double[N*N];
b=new double[N];
flag=new int[N];
//判断是否成功分配存储区
if(a==NULL||b==NULL||flag==NULL)
{
cout<<"分配存储区失败!\n";
exit(EXIT_FAILURE);
}
//读取线性方程组的增广矩阵
for(int i=0;i<N;++i)
{
for(int j=0;j<N;++j) cin>>*(a+i*N+j);
cin>>*(b+i);
}
//flag中存储的值对应相应的x值,当方程的解由于列变换交换后,flag中
//的值也相应交换,最后用于恢复解的顺序
for( i=0;i<N;++i) *(flag+i)=i;
}
void Matrix::Max(const int r)
{
double max=0;
for(int i=r;i<N;++i)
for(int j=r;j<N;++j)
{
if(max<fabs(*(a+i*N+j)))
{
max=fabs(*(a+i*N+j));
//设定最大主元的行、列
location.row=i;
location.column=j;
}
}
//最大主元小于输入的精度时,认为方程组无解,退出程序 if(max<=esp)
{
cout<<"方程组无解!\n";
exit(EXIT_FAILURE);
}
}
void Matrix::ChangeRC(const int r)
{
double temp;
//如果最大主元所在的行不在当前行,则进行行变换 if(location.row!=r)
{
for(int i=r;i<N;++i)
{
temp=*(a+r*N+i);
*(a+r*N+i)=*(a+location.row*N+i);
*(a+location.row*N+i)=temp;
}
temp=b[r];
b[r]=b[location.row];
b[location.row]=temp;
}
//若最大主元所在的列不在当前的r列,则进行列变换 if(location.column!=r)
{
for(int i=r;i<N;++i)
{
temp=*(a+i*N+r);
*(a+i*N+r)=*(a+i*N+location.column);
*(a+i*N+location.column)=temp;
}
//交换flag中的元素来标记方程解的位置变化
int temp1;
temp1=*(flag+r);
*(flag+r)=*(flag+location.column);
*(flag+location.column)=temp1;
}
}
void Matrix::Eliminate(const int r)
{
if(fabs(*(a+N*r+r))<=esp)
{
cout<<"方程组无解!\n";
exit(EXIT_FAILURE);
}
for(int i=r+1;i<N;++i)
{
for(int j=r+1;j<N;++j)
(*(a+i*N+j))-=(*(a+i*N+r))*(*(a+r*N+j))/(*(a+r*N+r)); (*(b+i))-=(*(b+r))*(*(a+i*N+r))/(*(a+r*N+r)); }
}
void Matrix::Result()const
{
if(fabs(*(a+N*(N-1)+N-1))<=esp)
{
cout<<"方程组无解!\n";
exit(EXIT_FAILURE);
}
double temp;
*(b+N-1)/=(*(a+N*(N-1)+N-1)); //求出X[N-1]
//依次求出X[i](i=N-2,N-3····,1)
for(int i=N-2;i>=0;--i)
{
temp=0;
for(int j=i+1;j<N;++j) temp+=((*(a+i*N+j))*(*(b+j))); *(b+i)=(*(b+i)-temp)/(*(a+i*N+i));
}
//根据flag中的数据用冒泡排序法恢复方程组解的次序 for(i=0;i<N-1;++i)
for(int j=0;j<N-i-1;++j)
if(*(flag+j)>*(flag+j+1))
{
int temp1;
//交换解的顺序
temp=*(b+j);
*(b+j)=*(b+j+1);
*(b+j+1)=temp;
//交换用于标记的元素的顺序
temp1=*(flag+j);
*(flag+j)=*(flag+j+1);
*(flag+j+1)=temp1;
}
}
void Matrix::Calculate()
{ //根据矩阵行数重复进行寻找最大主元、变换行或列、消元 for(int i=0;i<GetRank()-1;++i)
{
Max(i);
ChangeRC(i);
Eliminate(i);
}
Result();
}
int Matrix::GetRank()const
{
return N;//返回矩阵的行数
}
double Matrix::GetX(const int i)const
{
return *(b+i-1);
}
运行结果
追赶法求解方程组的算法:
1. 输入方程组的维数n,将主对角元素b(i)(i=0:n-1),,主对角元素左边的元素
a(i)(i=0:n-2),主对角元素右边的元素c(i)(i=0:n-2),右端项的元素f(i)(i=0:n-1)
2. 对方程组的系数矩阵作Crout分解, α(0)=b(0),对于i=0:n-2,
c(i):=β(i):= c(i)/b(i), b(i+1):=α(i+1):= b(i+1)-a(i)* β(i)
3.解方程组Ly=f
b(0):=y(0):=[f(0)/ α(0)]:=[f(0)/b(0)]
对于i=1:n-1, b(i):=y(i):=[f(i)-a(i-1)*y(i-1)]/b(i)
4..解方程组Ux=y
a(n-1):=x(n-1):=b(n-1)
对于i=n-2:0,a(i)=x(i):=b(i)-c(i)*a(i+1);
5.输出方程组的解a(0:n-1)
用追赶法求解方程组的源程序及运行结果
#include<iostream>
#include<stdlib.h>
using namespace std;
class MatrixThr
{
public:
MatrixThr();
~MatrixThr();
void SetMatrixThr(const int n);//设置三对角矩阵的数据
void Result();//计算三对角矩阵的解
double GetX(const int i)const;//取得第i个解,i从1开始
int GetN() const;//返回未知数的数目
private:
int N;//N为未知数的数目
//b为矩阵主对角线的元素首地址,a为主对角线左边一斜条元素的首地址, //c为主对角线右边一斜条元素首地址,f为方程组的常数首地址
double *a,*b,*c,*f;
};
int main()
{
MatrixThr matrix;
int n;
do{
cout<<"输入三对角方程组的变量的数目N:";
cin>>n;
}while(n<3);
cout<<"请依次输入三对角方程组每行的数据(0元素除外):\n";
matrix.SetMatrixThr(n); //计算方程组的解
matrix.Result();//输出方程组的解
cout<<"方程的解如下:\n";
for(int i=1;i<=matrix.GetN();++i) cout<<"X["<<i<<"]:"<<matrix.GetX(i)<<endl;
return 0;
}
MatrixThr::MatrixThr()
{ //初始化相关数据
N=0;
a=NULL;
b=NULL;
c=NULL;
f=NULL;
}
MatrixThr::~MatrixThr()
{ //释放分配的内存空间
delete []a;
delete []b;
delete []c;
delete []f;
}
void MatrixThr::SetMatrixThr(const int n)
{ //根据输入的未知数个数设置矩阵的数据
N=n;
a=new double[N];
b=new double[N];
c=new double[N];
f=new double[N];
//若内存分配失败,退出程序
if(a==NULL||b==NULL||c==NULL||f==NULL)
{
cout<<"初始化分配存储空间失败!\n";
exit(EXIT_FAILURE);
}
//依次输入三对角矩阵每行的元素
cin>>*b>>*c>>*f;
for(int i=1;i<N-1;++i) cin>>*(a+i-1)>>*(b+i)>>*(c+i)>>*(f+i); cin>>*(a+i-1)>>*(b+i)>>*(f+i);
}
void MatrixThr::Result()
{ //对系数矩阵A作Crout分解
for(int i=0;i<N-1;++i)
{ //将U中的α存于指针b中,L中的β存于指针c中
*(c+i)/=(*(b+i));
*(b+i+1)-=(*(a+i))*(*(c+i));
}
//解方程组Ly=f,求得的y值存于指针b中
*b=(*f)/(*b);
for(i=1;i<N;++i) *(b+i)=((*(f+i))-(*(a+i-1))*(*(b+i-1)))/(*(b+i));
//解方程组Ux=y,求得的x值存于指针a中
*(a+N-1)=*(b+N-1);
for(i=N-2;i>=0;--i) *(a+i)=*(b+i)-(*(c+i))*(*(a+i+1));
}
int MatrixThr::GetN()const
{
return N;
}
double MatrixThr::GetX(const int i)const
{
return *(a+i-1);
}
运行结果