测绘软件实习报告

时间:2024.4.20

实验一图的创建、遍历、及其MST的构建

实验目的

ö  图的创建 。

ö  基于深度优先的图的遍历算法的设计与实现 。

ö  基于广度优先的图的遍历算法的设计与实现 。

ö  基于Prim算法的最小生成树的构建。

ö  基于Kruskal算法的最小生成树的构建 。

实验过程


#include<iostream>

#include” KJL_Queue.h”

using namespace std;

//定义为prim服务的辅助结点

struct primnode

{public:

 char begvex;//开始结点

 char endvex;//结束结点

 int lowcost;//中间权值};

class KJL_Graphmtx//图的邻接矩阵定义

{ public:

         KJL_Graphmtx(int sz=DefaultVertices);//构造函数

         ~KJL_Graphmtx()//析构函数

         {delete []VerticesList;delete []Edge;}

         bool GraphEmpty()//判断图是否为空

         {        if(numEdges==0)return true;

                   else return false;     }

         bool GraphFull()//判断图是否为满

         {if(numVertices==maxVertices||numEdges==maxVertices*(maxVertices-1)/2)

                            return true;

                   else

                            return false;     }

int NumberOfVertices()//返回当前顶点数

         {                 return numVertices;         }

         int NumberOfEdges()//返回当前边数

         {                 return numEdges;   }

         char getValue(int i)//取顶点i的值,i不合理返回0

         {                 return i>=0&&i<=numVertices ? VerticesList[i] : NULL; }

         int getWeight(int v1,int v2)//取边(v1,v2)上的权值

         {                 return v1!=-1&&v2!=-1 ? Edge[v1][v2] : 0;      }

         int getFirstNeighbor(int v);//取顶点v的第一个邻接顶点

         int getNextNeighbor(int v,int w);//取v的邻接顶点w的下一邻接顶点

         bool insertVertex(char vertex);//插入顶点vertex

         bool insertEdge(int v1,int v2,int weight);//插入边(v1,v2),权为weight

         bool removeVertex(int v);//删去顶点v和所有与它相关联的边

         bool removeEdge(int v1,int v2);//在图中删去边(v1,v2)

         int getVertexPos(char vertex)//给出顶点vertex的位置,如果该顶点不在图内则返回-1

         {        for(int i=0;i<numVertices;i++)

                   if(VerticesList[i]==vertex) return i;

                   return -1; }

         int mini();//求图中所有边的最小权值

         bool input();//输入函数

         bool output();//输出函数

         void kruskal();//kruskal算法

         void prim();//prim算法

protected:

         int maxVertices;//图中最大顶点数

         int numEdges;//图中当前边数

         int numVertices;//图中当前顶点数       

private:

         char *VerticesList;//顶点表

         int * *Edge;//邻接矩阵

         int visit[50];//便利时的辅助工具

         primnode closeedge[50];//为实现prim 函数的辅助结点};

KJL_Graphmtx::KJL_Graphmtx(int sz)//构造函数

{        maxVertices=sz;

         numVertices=0;

         numEdges=0;

         int i,j;

         VerticesList=new char[maxVertices];//创建顶点表数组

         Edge=(int * *)new int *[maxVertices];//创建邻接矩阵数组

         for(i=0;i<maxVertices;i++)

                   Edge[i]=new int[maxVertices];

for(i=0;i<maxVertices;i++)//邻接矩阵初始化

                   for(j=0;j<maxVertices;j++)

                   Edge[i][j]=(i==j)? 0 : maxWeight;}

int KJL_Graphmtx::getFirstNeighbor(int v)//给出顶点位置v的第一个邻接顶点的位置,如果找不到,则函数返回-1

{        if(v!=-1)

         {        for(int i=0;i<numVertices;i++)

         if(Edge[v][i]>0&&Edge[v][i]<maxWeight)return i;   }

         return -1;}

int KJL_Graphmtx::getNextNeighbor(int v,int w)//给出顶点v的某邻接顶点w的下一个邻接顶点的位置,如果找不到,则函数返回-1

{        if(v!=-1&&w!=-1)

         {for(int i=w+1;i<numVertices;i++)

         if(Edge[v][i]>0&&Edge[v][i]<maxWeight) return i;  }

         return -1;}

bool KJL_Graphmtx::insertVertex(char vertex)//插入顶点vertex

{        if(numVertices==maxVertices) return false;//顶点表满,不插入

         VerticesList[numVertices++]=vertex;

         return true;}

bool KJL_Graphmtx::insertEdge(int v1,int v2,int weight)//插入边(v1,v2),权为weight

{if(v1!=-1&&v1<numVertices&&v2!=-1&&v2<numVertices&&Edge[v1][v2]==maxWeight)////插入条件(???)

         {                 Edge[v1][v2]=Edge[v2][v1]=weight;

                   numEdges++;

                   return true;      }

         else

                   return false;}

bool KJL_Graphmtx::removeVertex(int v)//删去顶点v和所有与它相关联的边

{        if(v<0&&v>=numVertices)return false;//v不在图中,不删除

         int i,j;

         VerticesList[v]=VerticesList[numVertices-1];//顶点表中删除该结点

         for(i=0;i<numVertices;i++)//减去与v相关联的边数

         if(Edge[i][v]>0&&Edge[i][v]<maxWeight) numEdges--;

         for(i=0;i<numVertices;i++)//用最后一列填补第v列

                   Edge[i][v]=Edge[i][numVertices-1];

         numVertices--;//顶点个数减1

         for(j=0;j<numVertices;j++)//用最后一行填补第v行

                   Edge[v][j]=Edge[numVertices-1][j];

         return true;}

bool KJL_Graphmtx::removeEdge(int v1,int v2)//在图中删去边(v1,v2)

{if(v1>-1&&v1<numVertices&&v2>-1&&v2<numVertices&&Edge[v1][v2]>0&&Edge[v1][v2]<maxWeight)

         {Edge[v1][v2]=Edge[v2][v1]=maxWeight;//删除边(v1,v2)

                   numEdges--;

                   return true;      }

         else

                   return false;}

bool KJL_Graphmtx::input()

{        int i,j,k,n,m;

         char e1,e2;

         int weight;

         cout<<"请输入顶点数和边数:"<<endl;

         cin>>n>>m;//输入顶点数n和边数m

         cout<<"请输入顶点的值:"<<endl;

         for(i=0;i<n;i++)//依次输入顶点的值

         {                 cin>>e1;

                   this->insertVertex(e1);    }

         i=0;

         while(i<m)

         {        cout<<"请输入端点信息:"<<endl;

         cin>>e1>>e2>>weight;//输入端点信息

         j=this->getVertexPos(e1);//查顶点号

                   k=this->getVertexPos(e2);

                   if(j==-1||k==-1)

                   cout<<"边两端点信息输入有误,请重新输入!"<<endl;

                   else

                   {        this->insertEdge(j,k,weight);

                            i++;  }}

         return true;}

bool KJL_Graphmtx::output()//输出函数

{        int i,j,n,m;

         char e1,e2;

         int w;

         n=this->NumberOfVertices();

         m=this->NumberOfEdges();

         cout<<"顶点的个数为:"<<n<<endl;

         cout<<"边的条数为:"<<m<<endl;

         cout<<"所有边的信息为:"<<endl;

         for(i=0;i<n;i++)

                   for(j=i+1;j<n;j++)

                   {        w=this->getWeight(i,j);

                            if(w>0&&w<maxWeight)

                            {        e1=this->getValue(i);

                                     e2=this->getValue(j);                 cout<<"("<<e1<<","<<e2<<","<<w<<")"<<endl;}}

         return true;}

int KJL_Graphmtx::mini()//求图中所有边的最小权值,并返回

{ static int i;

 int min=0;

 for (int j=0;j<numVertices;j++)

 {  if(!visit[j])

{if(closeedge[min].lowcost>closeedge[j].lowcost)

   {    min=j;   }  } }

 i=min;

cout<<"包括边("<<closeedge[i].begvex<<","<<closeedge[i].endvex<<")";

 return i;}

//图的深度优先搜索函数////////

void DFS(KJL_Graphmtx & G,int v,bool visited[]);//先声明函数,后使用

void DFS(KJL_Graphmtx & G,char & v)//从顶点v出发,对图G进行深度优先遍历的主要过程

{        int i,loc,n=G.NumberOfVertices();//取图中顶点的个数

         bool * visited=new bool[n];//创建辅助数组

         for(i=0;i<n;i++)//初始化辅助数组visited

         {                 visited[i]=0;      }

         loc=G.getVertexPos(v);//取得v结点在图中的位置

         DFS(G,loc,visited);//从顶点0开始深度优先搜索

         delete []visited;}

void DFS(KJL_Graphmtx & G,int v,bool visited[])//从顶点v出发,对图G进行深度优先遍历的子过程

//从顶点位置v出发,以深度优先的次序访问所有可读入的尚未访问过的顶点。

//算法中用到一个vistied,对已访问过的顶点做访问标记。

{        cout<<G.getValue(v)<<endl;//访问顶点v

         visited[v]=1;//顶点v作访问标记

         int w=G.getFirstNeighbor(v);//找v的第一个邻接顶点w

         while(w!=-1)//若邻接顶点w存在

         {        if(visited[w]==0)

         DFS(G,w,visited);//若w未被访问,递归访问顶点w

         w=G.getNextNeighbor(v,w);//取v排在w后的下一个邻接顶点         }}

//图的广度优先搜索函数////////

void BFS(KJL_Graphmtx G,char v)//从顶点v出发,以广度优先的次序横向搜索图,算法中使用了一个队列。

{        int i,w,n=G.NumberOfVertices();//去图中的定点个数

         bool *visited=new bool[n];//用来记录顶点是否被访问过,被访问值为1,为被访问值为0

         for(i=0;i<n;i++)//初始化

                   visited[i]=0;

int loc=G.getVertexPos(v);//取顶点v的位置号

cout<<G.getValue(loc)<<endl;//访问顶点v

         visited[loc]=1;//做已访问标记

         KJL_Queue Q;//定义一个辅助队列

Q.EnQueue(loc);//顶点进队,实现分层访问

         while(!Q.IsEmpty())//循环访问所有结点,判断队列是否为空

{Q.DeQueue(loc);//从队列中退出顶点loc

         w=G.getFirstNeighbor(loc);//找顶点loc的第一个邻接点w

                   while(w!=-1)//若邻接点w存在

                   {if(visited[w]==false)//若未被访问

{cout<<G.getValue(w)<<endl;//访问顶点w

visited[w]=1;//标记w已经被访问

Q.EnQueue(w);//顶点w进队列w=G.getNextNeighbor(loc,w);//找顶点loc的下一个邻接顶点,重复检测v的所有邻接顶点     }}

         delete [] visited;}

//////kruskal函数的实现//////

void KJL_Graphmtx::kruskal()

{ int a,b,k=0;

 int min=maxWeight;

 int Edge1[20][20];

 for (int m=0;m<numVertices;m++)

 visit[m]=m;//每一个顶点属于一颗树

 for (int i=0;i<numVertices;i++)

          for(int j=0;j<numVertices;j++)

                   Edge1[i][j]=Edge[i][j];

 while (k<numVertices-1)

 {        min=maxWeight;

           for (int i=0;i<numVertices;i++)

           { for (int j=0;j<numVertices;j++)

            { if (Edge1[i][j]<min)

                   { a=i;         b=j;  min=Edge1[i][j]; }}}

  if (visit[a]!=visit[b])

  { cout<<"包括边("<<VerticesList[a]<<","<<VerticesList[b]<<")";

            k++;

            for (int n=0;n<numVertices;n++)

            { if (visit[n]==visit[b]) visit[n]=visit[a];        }  }

  else   Edge1[a][b]=Edge[b][a]=maxWeight; }

 cout<<endl;}

////////////Prim函数的实现////

void KJL_Graphmtx::prim()

{        char u;

          cout<<"请输入起始顶点:"<<endl;    cin>>u;

          int i=this->getVertexPos(u);  visit[i]=1;

          for(int j=0;j<numVertices;j++)

          {closeedge[j].begvex=u;

           closeedge[j].endvex=VerticesList[j];

           closeedge[j].lowcost=Edge[i][j];  }

          for (int m=1;m<numVertices;m++)

          { int n=mini(); visit[n]=1;  closeedge[n].lowcost=maxWeight;

           for (int p=0;p<numVertices;p++)

           { if(!visit[p])

            { if(Edge[p][n]<closeedge[p].lowcost)

                   { closeedge[p].lowcost=Edge[p][n];

         closeedge[p].begvex=VerticesList[n];} } }         }}

实验结果

实验体会

经过这次实验让我更深刻的理解了C++类的的结构,能够对二维数组的动态开辟空间和释放空间有了更深刻的理解,对图的遍历及构建最小生成树也有了深刻的体会。

总之,在这次试验中,学到了许多,也提高了自己的编程能力。


实验二、快速排序算法的实现

实验目的


ö  选取表中一个元素r[k](一般选第一个元素),令x=r[k]称为控制关键字,用控制关键字和无序区中其余元素关键字进行比较

ö  设置两个指示器i,j,分别表示线性表第一个和最后一个元素位置

ö  将j逐渐减小,逐次比较r[j]与x,直到出现一个r[j]<x,然后将r[j]移动到r[i]位置。将i逐渐增大,并逐次比较r[i]与x,直到发现一个r[i]>x,然后将r[i]移动到r[j]位置

ö  重复上述过程,知道i=j位置,并将x移动到r[j]位置,此时线性表以x为界分割成两个子区间

ö  实现快速排序功能

实验过程

#include<iostream>

using namespace std;

const maxSize=100;

int partition(int data[],int first,int end)//在实现快速排序函数时要用,这是快速排序的一趟算法

{

         int i=first;

         int j=end;

         int temp;

         while(i<j)

         {

                   while(i<j&&data[i]<=data[j]) //向右扫描

                            j--;

                   if(i<j)

                   {

                            temp=data[i];

                            data[i]=data[j];

                            data[j]=temp;

                            i++;

                   }

                   while(i<j&&data[i]<=data[j]) //向左扫描

                            i++;

                   if(i<j)

                   {

                            temp=data[i];

                            data[i]=data[j];

                            data[j]=temp;

                            j--;

                   }

         }

         return i;

}

class KJL_CSort

{

public:     

         KJL_CSort();

         ~KJL_CSort();

public:      // 排序算法的具体实现

         void QuickSort();

         void input();

         void output();

private:    // 成员变量

         int *data;

         int first,end;

         int size;//当前数组大小

};

KJL_CSort::KJL_CSort()

{

         first =0;

         end=0;

         size=0;

         data=new int [maxSize];

         for(int j=0;j<maxSize;j++)

                   data[j]=0;

}

KJL_CSort::~KJL_CSort()

{

         delete []data;

}

void KJL_CSort::input()

{

         int i;

         cout<<"请输入数组大小:"<<endl;

         cin>>size;

         end=size-1;

         cout<<"输入数组的值:"<<endl;

         int m;

         for(i=0;i<size;i++)

         {

                   cin>>data[i];

         }

}

void KJL_CSort::output()

{

         int i;

         for(i=0;i<size;i++)

                   cout<<data[i]<<"  ";

         cout<<endl;

}

void KJL_CSort::QuickSort()

{

         int pivot;

         if(first<end)

         {

                   pivot=partition(data,first,end);

                   end=pivot-1;

                   QuickSort();

                   first=pivot+1;

                   QuickSort();

         }

         first=0;

         end=size-1;

}

void main()

{

         KJL_CSort biao;

         biao.input();

         cout<<"快速排序前的顺序:"<<endl;

         biao.output();

         biao.QuickSort();

         cout<<"快速排序后的顺序:"<<endl;

         biao.output();

}


实验结果

实验体会

快速排序法,是众多排序方法中的一种,这种方法的优点在于它的比较次数少,每经过一趟比较,都可以把一个无序的数组分成两个部分,左边的部分全部小于(大于)右边的部分。

在实现这个算法过程中,采用的时递归调用的方式。这让我对递归又有了更深层次的理解,对数组的排序,也不仅仅局限于冒泡,选择排序,在快速排序的基础上设计了以个快速排序类。




实验三、矩阵类的设计与实现

实验目的

ö  按照上述矩阵类的设计,完成相应函数的编码

ö  对于矩阵数据的存储,可以选用如下两种方式来实现

ö  使用double** _A来存储矩阵;        

实验过程


#include<iostream>

#include<cmath>

using namespace std;

const maxSize=100;

#define  maxnum 50

class KJL_CMatrix

{

public:

         KJL_CMatrix(); // 默认构造函数

         KJL_CMatrix(int row, int column); // 构造函数一

         KJL_CMatrix(const KJL_CMatrix& m); // 复制构造函数

         ~KJL_CMatrix(); // 默认析构函数

         KJL_CMatrix& operator=(const KJL_CMatrix& m); // 赋值运算符

         bool operator==(const KJL_CMatrix& m); // 比括较运算符

         bool operator!=(const KJL_CMatrix& m); // 比括较运算符

         KJL_CMatrix operator+(const KJL_CMatrix& m); // 加运算符

         KJL_CMatrix operator-(const KJL_CMatrix& m); // 减运算符

         KJL_CMatrix& operator+=(const KJL_CMatrix& m); //+=运算符

         KJL_CMatrix& operator-=(const KJL_CMatrix& m); // -=运算符

         KJL_CMatrix operator-();// 取负数

         KJL_CMatrix operator*(const KJL_CMatrix& m); // 乘法运算符

         void input();//矩阵输入

         void output(); // 输出该矩阵

         KJL_CMatrix transpose(); // 矩阵转置

         ////////////////////////////////////////////////////////////

         KJL_CMatrix yuzishi(int i,int j);//求矩阵的第(i,j)的余子式

         double  hanglieshi();//求矩阵的行列式

         KJL_CMatrix bansui();//求矩阵的伴随矩阵

         KJL_CMatrix inverse(); // 矩阵求逆(伴随矩阵除以行列式)

         //////////////////////////////////////////////////////////////

         KJL_CMatrix  inv();//矩阵求逆(用高斯约当法)

         KJL_CMatrix & change(int k,int l);//交换矩阵的第k行和第l行

         int max_cloumn(int k);//求矩阵第k列的最大行数

         //////////////////////////////////////////////////////////////

         // 设置(i,j)的值

         void setValue(int row, int column, double value) { _A[row][column] = value; }

         double getValue(int row, int column) const { return _A[row][column]; }

         // 设置行、列的值

         void setRow(const int row) { _row = row; }

         int getRow() const { return _row; }

         void setColunm(const int column) { _column = column; }

         int getColumn() const { return _column; }

public:// 成员变量

         double** _A;   // 或用这个定义vector<vector<double> > _A;

         int _row, /*行*/ _column; // 列

};

KJL_CMatrix::KJL_CMatrix()//矩阵默认构造函数

{

         _row=0;

         _column=0;

         _A=(double * *) new  double [maxSize];

         int i;

         for(i=0;i<maxSize;i++)

                   _A[i]=new double[maxSize];

         int j;

         for(i=0;i<maxSize;i++)

                   for(j=0;j<maxSize;j++)

                            _A[i][j]=0;

}

KJL_CMatrix::KJL_CMatrix(int row, int column)//构造函数重载

{

    _row=row;

         _column=column;

         _A=(double * *) new  double [maxSize];

         int i;

         for(i=0;i<maxSize;i++)

                   _A[i]=new double[maxSize];

         int j;

         for(i=0;i<maxSize;i++)

                   for(j=0;j<maxSize;j++)

                            _A[i][j]=0;

}

KJL_CMatrix::KJL_CMatrix(const KJL_CMatrix& m)//复制构造函数

{

         _row=m._row;

         _column=m._column;

         int i,j;

         _A=(double * *) new  double [maxSize];

         for(i=0;i<maxSize;i++)

                   _A[i]=new double[maxSize];

         for(i=0;i<maxSize;i++)//初始化

                   for(j=0;j<maxSize;j++)

                            _A[i][j]=0;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=m._A[i][j];

                   }

}

KJL_CMatrix::~KJL_CMatrix()//析构函数

{

         delete []_A;

}

void KJL_CMatrix::input()//输入函数

{

         int i,j;

         cout<<"请输入矩阵的行数:"<<endl;

         cin>>_row;

         cout<<"请输入矩阵的列数:"<<endl;

         cin>>_column;

         cout<<"请输入矩阵:"<<endl;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            cin>>_A[i][j];

                   }

}

void KJL_CMatrix::output()//输出函数

{

         int i,j;

         for(i=0;i<_row;i++)

         {        for(j=0;j<_column;j++)

                   {

                            cout<<_A[i][j]<<"  ";

                   }

                   cout<<endl;

         }

}

KJL_CMatrix & KJL_CMatrix::operator=(const KJL_CMatrix & m)//=函数重载

{

         _row=m._row;

         _column=m._column;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator-()//取负号负号重载

{

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=-_A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator+(const KJL_CMatrix& m)//加号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能相加!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=_A[i][j]+m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix& KJL_CMatrix::operator+=(const KJL_CMatrix& m)//+=符号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能+=!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]+=m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix& KJL_CMatrix::operator-=(const KJL_CMatrix& m)//-=符号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能-=!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]-=m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator-(const KJL_CMatrix& m)//减号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能相减!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=_A[i][j]-m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator*(const KJL_CMatrix& m)//乘号符号函数重载

{

         KJL_CMatrix temp(_row,m._column);

         if(_column!=m._row)

         {

                   cerr<<"矩阵不能相乘!"<<endl;

         }

         int i,j,n;

         for(i=0;i<_row;i++)

                   for(j=0;j<_row;j++)

                   {

                            for(n=0;n<_column;n++)

                                     temp._A[i][j]+=_A[i][n]*m._A[n][j];

                   }

         return temp;

}

bool KJL_CMatrix::operator ==(const KJL_CMatrix& m)//==函数重载

{

         if(_row!=m._row||_column!=m._column)

                   return false;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            if(_A[i][j]!=m._A[i][j])

                                     return false;

                   }

         return true;

}

bool KJL_CMatrix::operator !=(const KJL_CMatrix& m)//!=函数重载

{

         if(_row!=m._row||_column!=m._column)

                   return true;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            if(_A[i][j]!=m._A[i][j])

                                     return true;

                   }

         return false;

}

KJL_CMatrix KJL_CMatrix::transpose()//转置函数

{

         KJL_CMatrix tem;

         tem._row=this->_column;

         tem._column=this->_row;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            tem._A[j][i]=_A[i][j];

                   }

         return tem;

}

KJL_CMatrix KJL_CMatrix::yuzishi(int i,int j)//求矩阵的余子式

{

         KJL_CMatrix temp;

         temp._row=this->_row-1;

         temp._column=this->_column-1;

         int m,n,k=0,l;

         for(m=0;m<_row;m++)

         {

                   l=0;

                   for(n=0;n<_column;n++)

                   {

                            if(m!=i&&n!=j)

                            {

                                     temp._A[k][l]=_A[m][n];

                            }

                            if(n!=j) l++;

                   }

                   if(m!=i) k++;

         }

         return temp;

}

double KJL_CMatrix::hanglieshi()//求矩阵的行列式

{

         if(_row!=_column)

         {cerr<<"此矩阵无行列式"<<endl; }

         if(_row==1&&_column==1)

                   return _A[0][0];

         else

         {

                   int i;

                   double sum=0;

                   for(i=0;i<_column;i++)

                   {                 sum+=pow(-1,i)*_A[0][i]*this->yuzishi(0,i).hanglieshi();

                   }

                   return sum;

         }

}

KJL_CMatrix KJL_CMatrix::bansui()//求伴随矩阵

{

         KJL_CMatrix temp;

         temp._column=this->_column;

         temp._row=this->_row;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

         temp._A[i][j]=pow(-1,i+j)*this->yuzishi(i,j).hanglieshi();          }

         return temp;

}

KJL_CMatrix KJL_CMatrix::inverse()//矩阵求逆

{

         KJL_CMatrix temp;

         int n;

         n=this->hanglieshi();

         temp=this->bansui();

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            temp._A[i][j]/=n;

                   }

         return temp;

}

KJL_CMatrix & KJL_CMatrix::change(int k,int l)//交换矩阵的第k行和第l行

{

         int i;

         double j;

         for(i=0;i<_column;i++)

         {        j=_A[k][i];

                   _A[k][i]=_A[l][i];

                   _A[l][i]=j;

         }

         return *this;

}

int KJL_CMatrix::max_cloumn(int k)//求矩阵第k列中从第k个元素之后绝对值最大的行数

{        int m=k;

         double max=fabs(_A[k][k]);

         for(int i=k+1;i<_column;i++)

         {        if(fabs(_A[i][k])>max)

                   {        max=fabs(_A[i][k]);

                            m=i;          }

         }

         return m;

}

KJL_CMatrix   KJL_CMatrix::inv()//矩阵求逆,通过行列变换

{

         int i,j,m;

         KJL_CMatrix E1;

         E1=*this;

         if(this->_row!=this->_column)

         {

                   cerr<<"该矩阵不能求逆"<<endl;

         }

         else

         {        if(E1.hanglieshi()==0)

                   {cerr<<"该矩阵不可逆:"<<endl; }

                   else

                   {/////////把矩阵E赋值成单位阵

                            KJL_CMatrix E;//创建一个和当前方阵阶数相同的单位矩阵

                            E._row=E1._row;

                            E._column=E1._column;

                            for(i=0;i<E1._row;i++)

                                     for(j=0;j<E1._row;j++)

                                     {E._A[i][j]=0;}

                            for(i=0;i<E1._row;i++)

                                     E._A[i][i]=1;

                            //化上三角阵

                            int i,j,hang;

                            for(i=0;i<E1._column-1;i++)//

                            {        hang=E1.max_cloumn(i);

                                     if(hang!=i)

                                     {        E1.change(i,hang);

                                               E.change(i,hang);    }

                                     double xishu;                               for(m=i+1;m<E1._row;m++)//第m行

                                     {

                            xishu=E1._A[m][i]/E1._A[i][i];                                       for(j=0;j<E1._column;j++)

                                               {                                             E1._A[m][j]=E1._A[m][j]-xishu*E1._A[i][j];       E._A[m][j]=E._A[m][j]-xishu*E._A[i][j];}}               ////上面为求上三角阵                     }

                   ///////////////////////////化对角阵

                            for(i=this->_column-1;i>0;i--)//

                            {        double xishu1;

                                     for(m=0;m<i;m++)

                                     {        xishu1=E1._A[m][i]/E1._A[i][i];

                            for(j=0;j<this->_column;j++)

                                               {                                             E1._A[m][j]=E1._A[m][j]-xishu1*E1._A[i][j];                                         E._A[m][j]=E._A[m][j]-xishu1*E._A[i][j];

                                               }}}

///////////////////////////////////矩阵单位化

                            double xishu3;

                            for(i=0;i<E1._column;i++)

                            {        xishu3=1/E1._A[i][i];

                                     for(j=0;j<E1._column;j++)

                                     {        E1._A[i][j]*=xishu3;

                                               E._A[i][j]*=xishu3;}}                   return E;  }}}

void main()

{        KJL_CMatrix array1,array2,array3;

         array1.input();

         array2=array1.inv();

         array3=array2*array1;

         array1.output();

         array2.output();

         array3.output();}


实验结果

实验体会

这个实验,是真正考验我们对所学知识的掌握,这里综合了我们所学的C++面向对象类的设计,以及我们如何利用自己所学的知识,把它转换为代码C++程序。

比如在实现矩阵的转置和矩阵的求逆这方面。根据我们以前所学的线性代数的知识,我们知道,要求一个矩阵的逆,可以求它的伴随矩阵除以该矩阵的行列式。这里就涉及到怎么求矩阵的行列式的问题,这是一个递归调用的问题。

然而,老师又给我们提供了几种推荐的方法,列主元素法法,高斯约当消去法等等。通过构造一个跟需求矩阵同阶的单位矩阵,然后通过行变换把该矩阵变成单位阵,原来的单位阵也做相应变化,便得到所求的逆矩阵。这知识一些思想,有了这些思想,我们就可以写出程序得到我们想要的结果了。

这个实验还让我们复习了以前所学的函数重载,比如矩阵的运算,运算符重载等等。经过这次实验真是获益匪浅。大大提高了我得编程能力。


实验四、基于直接法(列主元素法)与迭代法

Jacobi迭代与Gauss-Seidel迭代法)的线性方程组求解

实验目的

基于直接法(列主元素法)与迭代法(Jacobi迭代与Gauss-Seidel迭代法)的线性方程组求解.对各种迭代的收敛条件,和收敛速度做个比较。掌握这些函数的实现。

实验过程


主要的几个函数:

KJL_CMatrix & KJL_CMatrix::change(int k,int l)//交换矩阵的第k行和第l行

{        int i;

         double j;

         for(i=0;i<_column;i++)

         {

                   j=_A[k][i];

                   _A[k][i]=_A[l][i];

                   _A[l][i]=j;

         }

         return *this;

}

int KJL_CMatrix::max_cloumn(int k)//求矩阵第k列中从第k个元素之后绝对值最大的行数

{        int m=k;

         double max=fabs(_A[k][k]);

         for(int i=k+1;i<_column;i++)

         {        if(fabs(_A[i][k])>max)

                   {        max=fabs(_A[i][k]);

                            m=i; }}

         return m;

}

KJL_CMatrix   KJL_CMatrix::inv()//矩阵求逆,通过行列变换

{

         int i,j,m;

         KJL_CMatrix E1;

         E1=*this;

         if(this->_row!=this->_column)

         {cerr<<"该矩阵不能求逆"<<endl; }

         else

         {

                   if(E1.hanglieshi()==0)

                   {cerr<<"该矩阵不可逆:"<<endl; }

                   else

         {///////把矩阵E赋值成单位阵

                            KJL_CMatrix E;//创建一个和当前方阵阶数相同的单位矩阵

                            E._row=E1._row;

                            E._column=E1._column;

                            for(i=0;i<E1._row;i++)

                                     for(j=0;j<E1._row;j++)

                                     {E._A[i][j]=0;}

                            for(i=0;i<E1._row;i++)

                                     E._A[i][i]=1;

                            //化上三角阵

                            int i,j,hang;

                            for(i=0;i<E1._column-1;i++)//

                            {        hang=E1.max_cloumn(i);

                                     if(hang!=i)

                                     {        E1.change(i,hang);

                                               E.change(i,hang);}

                                     double xishu;                               for(m=i+1;m<E1._row;m++)//第m行

                                     {

                            xishu=E1._A[m][i]/E1._A[i][i];                                       for(j=0;j<E1._column;j++)

                                               {                                             E1._A[m][j]=E1._A[m][j]-xishu*E1._A[i][j];       E._A[m][j]=E._A[m][j]-xishu*E._A[i][j];}}               ////上面为求上三角阵                     }

                   ///////////////////////////化对角阵

                            for(i=this->_column-1;i>0;i--)//

                            {        double xishu1;

                                     for(m=0;m<i;m++)

                                     {        xishu1=E1._A[m][i]/E1._A[i][i];

                            for(j=0;j<this->_column;j++)

                                               {                                             E1._A[m][j]=E1._A[m][j]-xishu1*E1._A[i][j];                                         E._A[m][j]=E._A[m][j]-xishu1*E._A[i][j];

                                               }}}

///////////////////////////////////矩阵单位化

                            double xishu3;

                            for(i=0;i<E1._column;i++)

                            {

                                     xishu3=1/E1._A[i][i];

                                     for(j=0;j<E1._column;j++)

                                     {        E1._A[i][j]*=xishu3;

                                               E._A[i][j]*=xishu3;}}                   return E;  }}}

void KJL_CMatrix::find(int& f)const

{   int i;

          for(i=0;i<this->_row;i++)

          if(this->_A[i][i]!=0) f=1;

                       else  f=0;

};

void  jacobi(const KJL_CMatrix& a)

{    int f=1;

         a.find(f);

         if(f==0)  {cerr<<"该矩阵不满足迭代求解条件!"<<endl; exit(1); }

else

{

         KJL_CMatrix x,w;

         x.setColunm(1);

         x.setRow(a.getColumn());

         w.setColunm(1);

         w.setRow(a.getColumn());

int i;

double z;

for(i=1;i<=x._row;i++)

         { cout<<"请输入等式右侧的第"<<i<<"个值:";

          cin>>z;

         w._A[i-1][0]=z;

         }

for(i=1;i<=x._row;i++)

         {   cout<<"请输入X"<<i<<"的近似值:";

           cin>>z;

          x.setValue(i, 1, z);

         }

i=1;

while(i<=20)

         {  int j, k;                  

           for(j=1;j<=x._row;j++)

           {   double sum=0.0;

               for(k=1;k<j;k++)

                            {sum=sum-(a._A[j-1][k-1])*(x._A[k-1][0]);}

               for(k=j+1;k<=x._row;k++)              {sum=sum-(a._A[j-1][k-1])*(x._A[k-1][0]);}

                     sum+=w._A[j-1][0];

                     x._A[j-1][0]=sum/a._A[j-1][j-1];

           }

           i++;

         }       

   for(i=1;i<=x._row;i++)

     cout<<"X"<<i<<" = "<<x._A[i-1][0]<<endl;

}}

实验结果

1、  解方程如下(列主元素法)

jacobi迭代矩阵D.inv()*(L+U)矩阵结果:

 

Gauss-Seidel矩阵(D-L).inv()*U矩阵结果:

 

                                                                                                               

实验体会

通过实验结果,和我们所学的知识知道,只要迭代矩阵的谱半径小于1,迭代就是收敛的,与右边所取得的近似值无关。这个实验是基于矩阵类的实现,进一步加深对矩阵操作的理解。右端对迭代收敛是无影响。                                                                                                                                                                   


实验五Windows绘图

实验目的

通过在C++ MFC中绘制各种图形,能够定义各种画刷、线条、颜色。能够绘制出Windows基本图形。

实验过程


#include "stdafx.h"

#include "cbs.h"

#include "cbsDoc.h"

#include "cbsView.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

// CCbsView

IMPLEMENT_DYNCREATE(CCbsView, CView)

BEGIN_MESSAGE_MAP(CCbsView, CView)

         //{{AFX_MSG_MAP(CCbsView)

         ON_WM_MOUSEMOVE()

         ON_WM_LBUTTONDOWN()

         ON_WM_LBUTTONUP()

         //}}AFX_MSG_MAP

         // Standard printing commands

         ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)

         ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)

         ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)

END_MESSAGE_MAP()

// CCbsView construction/destruction

CCbsView::CCbsView()

{

         // TODO: add construction code here

         this->m_bDragging=false;

}

CCbsView::~CCbsView()

{

}

BOOL CCbsView::PreCreateWindow(CREATESTRUCT& cs)

{

         // TODO: Modify the Window class or styles here by modifying

         //  the CREATESTRUCT cs

         return CView::PreCreateWindow(cs);

}

// CCbsView drawing

void CCbsView::OnDraw(CDC* pDC)

{        CCbsDoc* pDoc = GetDocument();

         ASSERT_VALID(pDoc);

         // TODO: add draw code for native data here

         pDC->SetViewportOrg(150,150); // 当前原点位置移动到(50, 50)的位置

         COLORREF  rgbBkClr = RGB(192,192,192);                                                 // 定义灰色

         pDC->SetBkColor(rgbBkClr);                                                                     // 背景色为灰色

         pDC->SetTextColor(RGB(0,0,128));// 文本颜色为兰色

         pDC->TextOut(250,10,"我*****的*****绘*****图*****板!");

         CPen  *pPenOld, PenNew;

         int  nPenStyle[]= {         

PS_SOLID,            // 实线

         PS_DOT,             // 点线

         PS_DASH,                     // 虚线

         PS_DASHDOT,        // 点划线

         PS_DASHDOTDOT,      // 双点划线

         PS_NULL,              // 空的边框

         PS_INSIDEFRAME,       // 边框实线

         };

         char   *strStyle[]={"Solid", "Dot", "Dash", "DashDot",

                            "DashDotDot", "Null", "InsideFrame"};

         pDC->TextOut(50, 65, "用不同样式的画笔绘图"); 

         pDC->TextOut(400, 40, "); 

         for(int  i=0; i<7; i++)

         { // 用不同样式的画笔绘图

if(PenNew.CreatePen(nPenStyle[i],1,RGB(0,0,0)))

                    { //创建画笔                    pPenOld=pDC->SelectObject(&PenNew);      // 选择画笔                          pDC->TextOut(45,90+20*i,strStyle[i]);

                            pDC->MoveTo(150,100+20*i);

                            pDC->LineTo(200,100+20*i);

                            pDC->SelectObject(pPenOld);     // 恢复原来的画笔

                            PenNew.DeleteObject();      // 删除底层的GDI对象

                            }

      else  {MessageBox("不能创建画笔!"); }

         }

         char  *strWidth[]={"1", "2", "3", "4", "5", "6", "7"};

                   pDC->TextOut(260, 65, "用不同宽度的画笔绘图");

         for(i=0; i<7; i++)

         { // 用不同宽度的画笔绘图

                   if(PenNew.CreatePen(PS_SOLID,i+1,RGB(0,0,0)))

                   {  // 创建画笔

         pPenOld=pDC->SelectObject(&PenNew);   // 选择画笔

                   pDC->TextOut(260, 90+20*i,strWidth[i]);

                   pDC->MoveTo(300, 100+20*i);

                   pDC->LineTo(400, 100+20*i);

                   pDC->SelectObject(pPenOld);    // 恢复原来的画笔

                   PenNew.DeleteObject();                // 删除底层的GDI对象

      }

      else     {   MessageBox("不能创建画笔!"); }

         }

         char  *strColor[]={"红","绿","蓝","黄","紫","青","灰"};

      COLORREF  rgbPenClr[]={RGB(255,0,0), RGB(0,255,0),

                         RGB(0,0,255), RGB(255,255,0), RGB(255,0,255),

                        RGB(0,255,255), RGB(192,192,192)};

      pDC->TextOut(460,65,"用不同颜色的画笔绘图");

      for(i=0; i<7; i++)

           {  // 用不同颜色的画笔绘图

               CPen  *pPenNew=new CPen(PS_INSIDEFRAME,10,rgbPenClr[i]); 

// 创建画笔的另一种方法                  pPenOld=pDC->SelectObject(pPenNew);   // 选择创建的画笔

                            pDC->TextOut(460,90+20*i, strColor[i]);

                            pDC->MoveTo(500,100+20*i);

                            pDC->LineTo(600,100+20*i);

                            pDC->SelectObject(pPenOld);    // 恢复原来的画笔

                            delete  pPenNew;       // 自动删除底层的GDI对象

      }

}

// CCbsView printing

BOOL CCbsView::OnPreparePrinting(CPrintInfo* pInfo)

{        // default preparation

         return DoPreparePrinting(pInfo);}

void CCbsView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

         // TODO: add extra initialization before printing

}

void CCbsView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

         // TODO: add cleanup after printing

}

// CCbsView diagnostics

#ifdef _DEBUG

void CCbsView::AssertValid() const

{

         CView::AssertValid();

}

void CCbsView::Dump(CDumpContext& dc) const

{        CView::Dump(dc);}

CCbsDoc* CCbsView::GetDocument() // non-debug version is inline

{

         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCbsDoc)));

         return (CCbsDoc*)m_pDocument;

}

#endif //_DEBUG

// CCbsView message handlers

void CCbsView::OnMouseMove(UINT nFlags, CPoint point)

{

         // TODO: Add your message handler code here and/or call default

         if(m_bDragging)

         {

                   CClientDC   dc(this);

                   OnPrepareDC(&dc);

                   dc.DPtoLP(&point);

                   dc.MoveTo(this->m_ptOrigin);

                   dc.LineTo(point);

                   m_ptOrigin = point;

         }

         CView::OnMouseMove(nFlags, point);

}

void CCbsView::OnLButtonDown(UINT nFlags, CPoint point)

{

         // TODO: Add your message handler code here and/or call default

         CClientDC   dc(this);

         OnPrepareDC(&dc);      // 调整设备环境的属性

         dc.DPtoLP(&point);       // 将设备坐标转换为逻辑坐标

         SetCapture();  // 捕捉鼠标

         //::SetCursor(m_hCross);  // 设置十字光标

         m_ptOrigin=point;

         m_bDragging=TRUE;  // 设置拖拽标记

         CView::OnLButtonDown(nFlags, point);

}

void CCbsView::OnLButtonUp(UINT nFlags, CPoint point)

{        // TODO: Add your message handler code here and/or call default

         m_bDragging = false;


实验结果

         实验结果运行不成功。

实验体会

由于这次实验是基于MFC的第一次操作,老师讲解的时候,我没有认真听讲。所以只能看别人的代码,通过学习别人的程序来加深自己的理解。上面都是看了别人的代码,进行了适当的修改而得来,让自己有点偷窃的感觉,没有真正领悟到实验中得精华。让我深表遗憾,当然在以后的学习中,我会加强对这方面的练习。




实验六、面向对象的高程网平差程序设计与实现

实验目的

在矩阵实现的基础上,通过对水准网平差。了解和掌握平差原理,在C++面向对象程序设计中,实现平差,要求得出平差值和平差精度,可能的话能画出误差椭圆。


实验过程

#include<iostream>

#include<cmath>

using namespace std;

const maxSize=100;

#define  maxnum 50

class KJL_CMatrix

{

public:

         KJL_CMatrix(); // 默认构造函数

         KJL_CMatrix(int row, int column); // 构造函数一

         KJL_CMatrix(const KJL_CMatrix& m); // 复制构造函数

         ~KJL_CMatrix(); // 默认析构函数

         KJL_CMatrix& operator=(const KJL_CMatrix& m); // 赋值运算符

         bool operator==(const KJL_CMatrix& m); // 比括较运算符

         bool operator!=(const KJL_CMatrix& m); // 比括较运算符

         KJL_CMatrix operator+(const KJL_CMatrix& m); // 加运算符

         KJL_CMatrix operator-(const KJL_CMatrix& m); // 减运算符

         KJL_CMatrix& operator+=(const KJL_CMatrix& m); //+=运算符

         KJL_CMatrix& operator-=(const KJL_CMatrix& m); // -=运算符

         KJL_CMatrix operator-();// 取负数

         KJL_CMatrix operator*(const KJL_CMatrix& m); // 乘法运算符

         void input();//矩阵输入

         void output(); // 输出该矩阵

         KJL_CMatrix transpose(); // 矩阵转置

         ////////////////////////////////////////////////////////////

         KJL_CMatrix yuzishi(int i,int j);//求矩阵的第(i,j)的余子式

         double  hanglieshi();//求矩阵的行列式

         KJL_CMatrix bansui();//求矩阵的伴随矩阵

         KJL_CMatrix inverse(); // 矩阵求逆(伴随矩阵除以行列式)

         //////////////////////////////////////////////////////////////

         KJL_CMatrix  inv();//矩阵求逆(用高斯约当法)

         KJL_CMatrix & change(int k,int l);//交换矩阵的第k行和第l行

         int max_cloumn(int k);//求矩阵第k列的最大行数

         //////////////////////////////////////////////////////////////

         // 设置(i,j)的值

         void setValue(int row, int column, double value) { _A[row][column] = value; }

         double getValue(int row, int column) const { return _A[row][column]; }

         // 设置行、列的值

         void setRow(const int row) { _row = row; }

         int getRow() const { return _row; }

         void setColunm(const int column) { _column = column; }

         int getColumn() const { return _column; }

public:// 成员变量

         double** _A;   // 或用这个定义vector<vector<double> > _A;

         int _row, /*行*/ _column; // 列

};

KJL_CMatrix::KJL_CMatrix()//矩阵默认构造函数

{

         _row=0;

         _column=0;

         _A=(double * *) new  double [maxSize];

         int i;

         for(i=0;i<maxSize;i++)

                   _A[i]=new double[maxSize];

         int j;

         for(i=0;i<maxSize;i++)

                   for(j=0;j<maxSize;j++)

                            _A[i][j]=0;

}

KJL_CMatrix::KJL_CMatrix(int row, int column)//构造函数重载

{

    _row=row;

         _column=column;

         _A=(double * *) new  double [maxSize];

         int i;

         for(i=0;i<maxSize;i++)

                   _A[i]=new double[maxSize];

         int j;

         for(i=0;i<maxSize;i++)

                   for(j=0;j<maxSize;j++)

                            _A[i][j]=0;

}

KJL_CMatrix::KJL_CMatrix(const KJL_CMatrix& m)//复制构造函数

{

         _row=m._row;

         _column=m._column;

         int i,j;

         _A=(double * *) new  double [maxSize];

         for(i=0;i<maxSize;i++)

                   _A[i]=new double[maxSize];

         for(i=0;i<maxSize;i++)//初始化

                   for(j=0;j<maxSize;j++)

                            _A[i][j]=0;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=m._A[i][j];

                   }

}

KJL_CMatrix::~KJL_CMatrix()//析构函数

{

         delete []_A;

}

void KJL_CMatrix::input()//输入函数

{

         int i,j;

         cout<<"请输入矩阵的行数:"<<endl;

         cin>>_row;

         cout<<"请输入矩阵的列数:"<<endl;

         cin>>_column;

         cout<<"请输入矩阵:"<<endl;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            cin>>_A[i][j];

                   }

}

void KJL_CMatrix::output()//输出函数

{

         int i,j;

         for(i=0;i<_row;i++)

         {        for(j=0;j<_column;j++)

                   {

                            cout<<_A[i][j]<<"  ";

                   }

                   cout<<endl;

         }

}

KJL_CMatrix & KJL_CMatrix::operator=(const KJL_CMatrix & m)//=函数重载

{

         _row=m._row;

         _column=m._column;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator-()//取负号负号重载

{

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=-_A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator+(const KJL_CMatrix& m)//加号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能相加!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=_A[i][j]+m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix& KJL_CMatrix::operator+=(const KJL_CMatrix& m)//+=符号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能+=!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]+=m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix& KJL_CMatrix::operator-=(const KJL_CMatrix& m)//-=符号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能-=!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]-=m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator-(const KJL_CMatrix& m)//减号函数重载

{

         if(_row!=m._row||_column!=m._column)

         {

                   cerr<<"矩阵不能相减!"<<endl;

         }

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            _A[i][j]=_A[i][j]-m._A[i][j];

                   }

         return *this;

}

KJL_CMatrix KJL_CMatrix::operator*(const KJL_CMatrix& m)//乘号符号函数重载

{

         KJL_CMatrix temp(_row,m._column);

         if(_column!=m._row)

         {

                   cerr<<"矩阵不能相乘!"<<endl;

         }

         int i,j,n;

         for(i=0;i<_row;i++)

                   for(j=0;j<_row;j++)

                   {

                            for(n=0;n<_column;n++)

                                     temp._A[i][j]+=_A[i][n]*m._A[n][j];

                   }

         return temp;

}

bool KJL_CMatrix::operator ==(const KJL_CMatrix& m)//==函数重载

{

         if(_row!=m._row||_column!=m._column)

                   return false;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            if(_A[i][j]!=m._A[i][j])

                                     return false;

                   }

         return true;

}

bool KJL_CMatrix::operator !=(const KJL_CMatrix& m)//!=函数重载

{

         if(_row!=m._row||_column!=m._column)

                   return true;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            if(_A[i][j]!=m._A[i][j])

                                     return true;

                   }

         return false;

}

KJL_CMatrix KJL_CMatrix::transpose()//转置函数

{

         KJL_CMatrix tem;

         tem._row=this->_column;

         tem._column=this->_row;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            tem._A[j][i]=_A[i][j];

                   }

         return tem;

}

KJL_CMatrix KJL_CMatrix::yuzishi(int i,int j)//求矩阵的余子式

{

         KJL_CMatrix temp;

         temp._row=this->_row-1;

         temp._column=this->_column-1;

         int m,n,k=0,l;

         for(m=0;m<_row;m++)

         {

                   l=0;

                   for(n=0;n<_column;n++)

                   {

                            if(m!=i&&n!=j)

                            {

                                     temp._A[k][l]=_A[m][n];

                            }

                            if(n!=j) l++;

                   }

                   if(m!=i) k++;

         }

         return temp;

}

double KJL_CMatrix::hanglieshi()//求矩阵的行列式

{

         if(_row!=_column)

         {

                   cerr<<"此矩阵无行列式"<<endl;

         }

         if(_row==1&&_column==1)

                   return _A[0][0];

         else

         {

                   int i;

                   double sum=0;

                   for(i=0;i<_column;i++)

                   {                 sum+=pow(-1,i)*_A[0][i]*this->yuzishi(0,i).hanglieshi();

                   }

                   return sum;

         }

}

KJL_CMatrix KJL_CMatrix::bansui()//求伴随矩阵

{

         KJL_CMatrix temp;

         temp._column=this->_column;

         temp._row=this->_row;

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {                           temp._A[i][j]=pow(-1,i+j)*this->yuzishi(i,j).hanglieshi();

                   }

         return temp;

}

KJL_CMatrix KJL_CMatrix::inverse()//矩阵求逆

{

         KJL_CMatrix temp;

         int n;

         n=this->hanglieshi();

         temp=this->bansui();

         int i,j;

         for(i=0;i<_row;i++)

                   for(j=0;j<_column;j++)

                   {

                            temp._A[i][j]/=n;

                   }

         return temp;

}

KJL_CMatrix & KJL_CMatrix::change(int k,int l)//交换矩阵的第k行和第l行

{

         int i;

         double j;

         for(i=0;i<_column;i++)

         {

                   j=_A[k][i];

                   _A[k][i]=_A[l][i];

                   _A[l][i]=j;

         }

         return *this;

}

int KJL_CMatrix::max_cloumn(int k)//求矩阵第k列中从第k个元素之后绝对值最大的行数

{

         int m=k;

         double max=fabs(_A[k][k]);

         for(int i=k+1;i<_column;i++)

         {

                   if(fabs(_A[i][k])>max)

                   {

                            max=fabs(_A[i][k]);

                            m=i;

                   }

         }

         return m;

}

KJL_CMatrix   KJL_CMatrix::inv()//矩阵求逆,通过行列变换

{

         int i,j,m;

         KJL_CMatrix E1;

         E1=*this;

         if(this->_row!=this->_column)

         {

                   cerr<<"该矩阵不能求逆"<<endl;

         }

         else

         {

                   if(E1.hanglieshi()==0)

                   {

                            cerr<<"该矩阵不可逆:"<<endl;

                   }

                   else

                   {

                            /////////////把矩阵E赋值成单位阵

                            KJL_CMatrix E;//创建一个和当前方阵阶数相同的单位矩阵

                            E._row=E1._row;

                            E._column=E1._column;

                            for(i=0;i<E1._row;i++)

                                      for(j=0;j<E1._row;j++)

                                     {

                                               E._A[i][j]=0;

                                     }

                            for(i=0;i<E1._row;i++)

                                     E._A[i][i]=1;

                            //化上三角阵

                            int i,j,hang;

                            for(i=0;i<E1._column-1;i++)//

                            {

                                     hang=E1.max_cloumn(i);

                                     if(hang!=i)

                                     {

                                               E1.change(i,hang);

                                               E.change(i,hang);

                                     }

                                     double xishu;

                                     for(m=i+1;m<E1._row;m++)//第m行

                                     {

                                               xishu=E1._A[m][i]/E1._A[i][i];

                                               for(j=0;j<E1._column;j++)

                                               {                                                       E1._A[m][j]=E1._A[m][j]-xishu*E1._A[i][j];

                                     E._A[m][j]=E._A[m][j]-xishu*E._A[i][j];

                                               }

                                     }

                                     ///////////////////////////////////////////////上面为求上三角阵

                            }

                                     ///////////////////////////化对角阵

                            for(i=this->_column-1;i>0;i--)//

                            {

                                     double xishu1;

                                     for(m=0;m<i;m++)

                                     {

                                               xishu1=E1._A[m][i]/E1._A[i][i];

                                               for(j=0;j<this->_column;j++)

                                               {                                    E1._A[m][j]=E1._A[m][j]-xishu1*E1._A[i][j];                                         E._A[m][j]=E._A[m][j]-xishu1*E._A[i][j];

                                               }

                                     }

                            }

                   ///////////////////////////////////矩阵单位化

                            double xishu3;

                            for(i=0;i<E1._column;i++)

                            {

                                     xishu3=1/E1._A[i][i];

                                     for(j=0;j<E1._column;j++)

                                     {

                                               E1._A[i][j]*=xishu3;

                                               E._A[i][j]*=xishu3;

                                     }

                            }

                            return E;

                   }

         }

}

struct KJL_gaocha//高差信息

{

                   double      value;                 // 观测值

                   double     weight;    // 权重

                   long startPoint;        // 起始点编号

                   long endPoint; // 终点编号

};

//水准点类的设计

struct  KJL_shzpoint     

{        // 高程平差值=高程值+高程值改正数

                   long         bh;             // 水准点编号

                   double     eleValue; // 高程值

                   double     dv;             // 高程值改正数(初始化为0)

                   bool         isKnown;  // 是否为已知点

};

//水准网设计

class KJL_shzwNet

{

public:      // 成员函数

         KJL_shzwNet(){numgaocha=0;numPoints=0;numKnPoint=0;};                // 构造函数

         ~KJL_shzwNet(){};             // 析构函数

     void input();//水准网输入函数

          void output();//水准网输出函数

     void jsgc();////求每个点得近似高程

          int  getgczs(){return numgaocha;}   //返回观测值数目

          int  getzds(){return numPoints;}    //返回总点数

          int  getyzds(){return numKnPoint;}  //返回已知点数

          int  getwzds(){return numPoints-numKnPoint;}   //返回未知点数

          double  getgcValue(int i){return this->gczhi[i-1].eleValue;}  //获得高程值

          long getgcbh(int i){return gczhi[i-1].bh;}  //返回高程点编号

          void  setgczhi(int i, double dv){gczhi[i-1].eleValue+=dv;}   //改正高程值

          void setdv(int i,double dv){this->gczhi[i-1].dv=dv;}  //修改改正数

          double getdv(int i){return gczhi[i-1].dv;}  //返回改正数

          friend void xishu(KJL_CMatrix& B, KJL_CMatrix& X,KJL_shzwNet A);  //求取系数矩阵和未知点高程矩阵

          friend void  quanzhen(KJL_CMatrix& Q, KJL_shzwNet A);     //求取权阵

          friend void  l_zhen(  KJL_CMatrix& l ,KJL_CMatrix& L, KJL_shzwNet A);   //求取观测值L矩阵和l阵

public:      // 成员变量

         int numgaocha;        // 高差总数

         int numPoints;                   // 水准网中点的总数目

         int numKnPoint;                          //水准网中已知点的数目

         KJL_gaocha edVec[maxnum]; // 观测值数组

         KJL_shzpoint gczhi[maxnum];         // 水准点数组

};

void KJL_shzwNet::input()

{

         int a,b,c,i;

         double m,n,k;

         cout<<"请输入水准网中水准点总数和已知点数:"<<endl;

         cin>>a>>b;

         this->numPoints=a;

         this->numKnPoint=b;

         for(i=0;i<a;i++)//对水准网中的点进行编号,并对水准点进行初始化

         {

                   gczhi[i].bh=i+1;

                   gczhi[i].dv=0;

                   gczhi[i].eleValue=0;

                   gczhi[i].isKnown=0;

         }

         for(i=0;i<b;i++)//为水准网中的已知点输入高程

         {

                   cout<<"请输入第"<<i+1<<"个已知点的高程值:"<<endl;

                   cin>>m;

                   gczhi[i].eleValue=m;

                   gczhi[i].isKnown=1;

         }

         cout<<"请输入观测值的个数:"<<endl;

         cin>>c;

         this->numgaocha=c;

         for(i=0;i<this->numgaocha;i++)//输入观测值信息

         {

                   cout<<"请输入第"<<i+1<<"段观测段的高差值(m)、长度(km)、起始编号和终点编号"<<endl;

                   cin>>k>>n>>a>>b;

                   this->edVec[i].value=k;

                   this->edVec[i].weight=n;

                   this->edVec[i].startPoint=a;

                   this->edVec[i].endPoint=b;

         }

}

void KJL_shzwNet::output()

{

         int i;

         for(i=0;i<this->numPoints;i++)//输出水准点的信息

                   cout<<"编号为"<<this->gczhi[i].bh<<"的高程值为:"<<this->gczhi[i].eleValue<<endl;

         for(i=0;i<this->numgaocha;i++)//输出高差的信息

                   cout<<"观测段"<<i+1<<"平差后的值为:"<<this->edVec[i].value<<endl;

}

void KJL_shzwNet::jsgc()//求每个点得近似高程

{

         int i,j;

         for(i=0;i<this->numgaocha;i++)

         {//如果高差观测段的起始点高程值不为0,结束点高程为0 则:结束点高程=等于起始点高程+该测段的高差值 (0是默认值,代表还没参与计算)

        //如果高差观测段的起始点高程值为0,结束点高程为不0 则:起始点高程=等于结束点高程-该测段的高差值          if(this->gczhi[this->edVec[i].startPoint-1].eleValue!=0&&this->gczhi[this->edVec[i].endPoint-1].eleValue==0)

                   {                 this->gczhi[this->edVec[i].endPoint-1].eleValue=this->gczhi[this->edVec[i].startPoint-1].eleValue+this->edVec[i].value;

                   }else if(this->gczhi[this->edVec[i].startPoint-1].eleValue==0&&this->gczhi[this->edVec[i].endPoint-1].eleValue!=0)

                   {                           this->gczhi[this->edVec[i].startPoint-1].eleValue=this->gczhi[this->edVec[i].endPoint-1].eleValue-this->edVec[i].value;

                   }

         }

         for(j=this->numKnPoint;j<this->numPoints;j++)

         {//如果水准点的高程等于0则执行下面语句

                   if(this->gczhi[j].eleValue==0)

                   {

                            for(i=0;i<this->numgaocha;i++)

                            {//如果观测段的起始点等于水准点的编号  并且结束点得高程不为0则该该起始点的高程等于结束点高程减去高差值(观测值)                                     if(this->edVec[i].startPoint==this->gczhi[i].bh&&this->gczhi[this->edVec[i].endPoint-1].eleValue!=0)

                                     {                           this->gczhi[i].eleValue=this->gczhi[this->edVec[i].endPoint-1].eleValue-this->edVec[i].value;

                                     }//如果观测段的结束点等于水准点的编号  并且起始点点得高程不为0则该该结束点的高程等于起始点高程加上高差值(观测值)

                                     else if(this->edVec[i].endPoint==this->gczhi[i].bh&&this->gczhi[this->edVec[i].startPoint-1].eleValue!=0)

                                     {                                    this->gczhi[i].eleValue=this->gczhi[this->edVec[i].startPoint-1].eleValue+this->edVec[i].value;

                                     }

                            }

                   }

         }

}

void xishu(KJL_CMatrix & B, KJL_CMatrix & X,KJL_shzwNet A)//友元函数,求误差方程得系数矩阵

{

         int i,j;

         for(i=0;i<B.getRow();i++)

          for(j=0;j<B.getColumn();j++)

          {

                    B._A[i][j]=0;

          }

         for(i=0;i<A.getgczs();i++)

         {//如果起始点为已知点并且结束点为未知点 则系数设置如下                if(A.gczhi[A.edVec[i].startPoint-1].isKnown==1&&A.gczhi[A.edVec[i].endPoint-1].isKnown==0)

                   {

         B._A[i][A.edVec[i].endPoint-A.getyzds()-1]=1;

                   }//如果起始点为未知点并且结束点为已知点 则系数设置如下

                   else if(A.gczhi[A.edVec[i].startPoint-1].isKnown==0&&A.gczhi[A.edVec[i].endPoint-1].isKnown==1)

                   {                           B._A[i][A.edVec[i].startPoint-A.getyzds()-1]=-1;

                   }//如果起始点和结束点均为未知点 则系数设置如下

                   else if(A.gczhi[A.edVec[i].startPoint-1].isKnown==0&&A.gczhi[A.edVec[i].endPoint-1].isKnown==0)

                   {                 B._A[i][A.edVec[i].endPoint-A.numKnPoint-1]=1;

         B._A[i][A.edVec[i].startPoint-A.numKnPoint-1]=-1;

                   }

         }

         for(i=0;i<X._row;i++)

         {//未知点的近似高程矩阵

         X._A[i][0]=A.gczhi[A.numKnPoint+i].eleValue;

         }

}

void quanzhen(KJL_CMatrix & P,KJL_shzwNet A)//求权阵,与距离(单位km)的长度成反比

{        int i,j;

         double sum=0;

         double avg;

         for(i=0;i<A.numgaocha;i++)

sum+=A.edVec[i].weight;//水准路线的总长度

avg=sum/A.numgaocha;//水准路线平均长度

                   for(i=0;i<P._row;i++)

                   {

                            for(j=0;j<P._column;j++)

                                     P._A[i][j]=0;

                   }

                   for(i=0;i<P._row;i++)

                   P._A[i][i]=avg/A.edVec[i].weight;

}

void l_zhen(KJL_CMatrix & l,KJL_CMatrix &L,KJL_shzwNet A)//求取观测值L矩阵和l阵

{

         int i;

         double m;

         for(i=0;i<A.getgczs();i++)

         {

                   L._A[i][0]=A.edVec[i].value;

         }

         for(i=0;i<l._row;i++)

         {//(起始点高程+高差-结束点高程)*1000作为l阵                  m=(A.gczhi[A.edVec[i].startPoint-1].eleValue+A.edVec[i].value-A.gczhi[A.edVec[i].endPoint-1].eleValue)*1000;

                   l._A[i][0]=m;

         }

}

void main()

{

         KJL_shzwNet A;

         A.input();

         A.jsgc();//V=BX-l   =>x=NBB.inv()*B.transpose()*P*l

         KJL_CMatrix B(A.getgczs(),A.getwzds());

         KJL_CMatrix P(A.getgczs(),A.getgczs());

         KJL_CMatrix X(A.getwzds(),1);

         KJL_CMatrix l(A.getgczs(),1);

         KJL_CMatrix V(A.getgczs(),1);

    KJL_CMatrix    NBB(A.getwzds(),A.getwzds());

         KJL_CMatrix    x(A.getwzds(),1);

         KJL_CMatrix L(A.getgczs(),1);

         KJL_CMatrix VtpV(1,1);

         xishu(B,X,A);

         quanzhen(P,A);

         l_zhen(l,L,A);

         NBB=B.transpose()*P*B;

         x=NBB.inv()*B.transpose()*P*L;

         int i,j;

         for(i=A.getyzds()+1;i<=A.getzds();i++)

         {       

A.setdv(i,(x._A[i-A.numKnPoint-1][0]/1000));

             A.setgczhi(i,A.getdv(i));

                   cout<<"平差后编号为"<<A.getgcbh(i)<<"的点高程值:"<<A.getgcValue(i)<<"米"<<endl;

         }

   V=B*x-l;

   for(j=0;j<V._row;j++)

       cout<<"第"<<j+1<<"段观测高差平差值为:"<<(L._A[j][0]+V._A[j][0]/1000)<<"米"<<endl;

   VtpV=V.transpose()*P*V;

   cout<<"平差后单位权中误差为:"<<"+(-)"<<sqrt(VtpV._A[0][0]/A.getwzds())<<"毫米"<<endl;

}


实验结果

实验体会

         通过这次实验,让我不仅对以前所学的测量平差有所复习,也对最小二乘原理有了深刻了解。

在这个实验中,最关键的问题,当然是矩阵的实现,由于在实验三中我们对矩阵类已经实现了,所以当下需要解决的问题就是理解水准网平差的原理,水准网平差的过程。有了这些知识,我们需要解决的就是,如何构建一个水准网,在构建水准网的过程中,我们需要建立一个水准点类,和观测边类。有了这些先验的知识,对平差过程中,才会有所眉目。

在所有的结构和类都已经定义好了,剩下的就是逻辑思想了。

我们知道对于水准网平差过程中,我们所使用的是间接平差原理。V=BX-L;

VTPV=min的原理,在如何求B阵是解决问题的关键,因为水准网的方程式都是线性的,所以构建系数阵很方便。如果观测段是从已知点到未知点则系数阵为0,-1.如果观测段是从未知点到已知点则系数阵为1,0.如果观测段是冲未知点到未知点则系数阵是1,-1.利用这种思想很快就可以建立系数阵。对权阵P的构建也比较简单,因为P与距离成反比。用平均距离除以该距离作为权。L阵就是观测阵。有了这些基本矩阵,就很容易求出V,和L的平差值。

再利用sqrt(VTPV/(n-t))便求出了整个单位权中误差。

通过这次实验,把自己所学的知识真正利用到实际中了,这是一次体验,也是一次飞跃,有了这次实验的历练,对理解和学习C++也不再像以前那样盲目和不知所措,知道了如何学以致用。

更多相关推荐:
测量实习报告范文

一:实习的目的、任务、测区概况目的:实习是工程测量教学的重要组成部分,除验证课堂理论外,还是巩固和深化课堂所学知识的环节,更是培养学生动手能力和训练严格的科学态度和作风的手段。通过控制网的建立、地形点的测绘、手…

测量学实习报告(范文)

测量学实习报告目录一、前言--------------------------------------------------2二、实习的目的与任务-------------------------------…

工程测量实习报告范文

一.实习目的:1.联系水准仪的安置、整平、瞄准与读书和怎样测定地面两点间的高程;2.掌握经纬仪对中,整平,瞄准与读书等基本操作要领;3.掌握钢尺量距的一般方法;4.练习用经纬仪和水准仪测绘地形图;5.培养学生综…

工程测量实习报告范文

过去的两个星期中在老师的带领下我们开始了对工程测量这门课程的实习工程测量这门课是需要理论与实际结合的实习是大学生活的第二课堂是检验真理的试金石在课堂上书本中抽象的叙述说明往往使我们一下难以很好掌握但当我们面对着...

工程测量实习报告范文

工程测量实习,作为土木工程专业一门基本的必修专业实践课,对我们学土木工程专业学生来说,它的重要性不言而喻。学测量不仅是获取书本的理论知识,更是培养我们的动手操作能力和对课本理论知识的深入理解总结,以及体会测量思…

测量学实习报告范文总结

测量学实习报告目录前言第一章测区概况第二章平面控制测量第三章高程控制测量第四章地形图测绘第五章实习感想参考文献前言一实习目的1巩固和加深课堂所学理论知识培养学生理论联系实际的能力动手能力实事求是的科学态度刻苦耐...

测绘工程专业实习总结范文

《浙江大学优秀实习总结汇编》测绘工程岗位工作实习期总结转眼之间,两个月的实习期即将结束,回顾这两个月的实习工作,感触很深,收获颇丰。这两个月,在领导和同事们的悉心关怀和指导下,通过我自身的不懈努力,我学到了人生…

房屋调查测量实习报告

房屋面积调查实习报告为全面掌握青山湖区罗家镇房屋建设现状确保城镇总体规划的顺利实施根据中华人民共和国城市规划法中华人民共和国城市房地产管理法等法律法规规定市政府决定对青山湖区罗家镇房屋进行一次全面普查为做好此项...

工程测量实习报告[1]

上海应用技术学院工程测量实习报告姓名王春荣专业安全工程学号10106311131上海应用技术学院目录一实习时间5二实习地点5三小组成员5四指导教师5五实习目的5六实习设备5七实习内容5八实习步骤61水准测量61...

20xx测量实习报告范文

20xx测量实习报告范文第1篇测量实习报告范文工程测量实习作为土木工程专业一门基本的必修专业实践课对我们学土木工程专业学生来说它的重要性不言而喻学测量不仅是获取书本的理论知识更是培养我们的动手操作能力和对课本理...

测量学实习报告(完整版)

测量学实习报告册班级xxx组号xx组长xxx组员xxx指导教师xxx1目录一前言21实习时间22实习地点23实习小组信息24实习目的及要求25实习任务及内容2二控制测量闭合导线31控制点布置32闭合导线水准测量...

测量实习报告模板

前言在20xx至20xx学年第一学期末自20xx年12月27日起我们进行了为期7天的工程测量实习这次实习的内容是对工程测量知识的实践化实习的要求是让每个同学都对工程测量的实际操作能够达到基本掌握的程度这次实习与...

测绘实习报告范文(31篇)