首页 > 其他分享 >【学习笔记】简单数论-高斯消元与线性空间

【学习笔记】简单数论-高斯消元与线性空间

时间:2023-08-20 21:34:09浏览次数:36  
标签:系数 方程组 数论 线性方程组 矩阵 笔记 非零 高斯消

友情提示

线性方程组

  • 线性方程组是由 \(M\) 个 \(N\) 元一次方程共同构成的。
  • 线性方程组的所有系数可以写成一个 \(M\) 行 \(N\) 列的系数矩阵,再加上每个方程等号右侧的常数,可以写成 一个 \(M\) 行 \(N+1\) 列的增广矩阵。
  • 对增广矩阵的三类操作(初等行变化):
    • 用一个非零的数乘某一行。
    • 把其中一行的若干倍加到另一行上。
    • 交换两行的位置。
  • 用若干次初等行变化求解方程组,最后得到的矩阵被称为阶梯形矩阵,它的系数矩阵部分被称为上三角矩阵,从下往上依次带回方程组,即可得到每个未知数的解;将其进一步化简最后得到的矩阵被称为简化阶梯形矩阵,它的系数矩阵部分是一个对角矩阵,该矩阵直接给出了方程组的解(这部分可能有些难懂,建议参考蓝书)。

高斯消元(约旦消元)

  • 通过初等行列变化把增广矩阵变为简化阶梯形矩阵的线性方程组求解算法就是高斯消元算法。

  • 思想:对于每个未知数 \(x_i\) ,找到一个 \(x_i\) 的系数非零但 \(x_1 \sim x_{i-1}\) 的系数都为零的方程,然后用初等行变化把其他方程的 \(x_i\) 的系数全部消成零。

  • 特殊情形:

    • 在高斯消元过程中,可能出现 \(0=d\) 这样的方程,其中 \(d\) 是一个非零常数,表明原方程组中某些方程之间存在矛盾,有原方程组无实数解。
    • 在高斯消元过程中,有可能找不到 \(x_i\) 的系数非零但 \(x_1 \sim x_{i-1}\) 的系数都为零的方程,此时有原方程组有无穷多实数解。将存在 \(x_i\) 的系数非零但 \(x_1 \sim x_{i-1}\) 的系数都为零的方程中的 \(x_i\) 称为主元,否则称为自由元。
      • 对于每个主元,整个简化阶梯形矩阵中有且仅有一个位置 \((i,j)\) 满足该主元的系数非零,第 \(j\) 列的其他位置都为零,第 \(i\) 行的第 \(1 \sim j-1\) 列都为零。
  • 总结:

    • 高斯消元完成后,若存在系数全为零、常数不为零的行,则原方程组无实数解;若系数不全为零的行恰好有 \(n\) 个,则说明有 \(n\) 个主元,原方程组有唯一解;若系数不全为零的行有 \(k(k<n)\) 个,则说明有 \(k\) 个主元, \(n-k\) 个自由元,原方程组有无穷多实数解。
  • 例题:

    const double eps=1e-12;//考虑浮点数误差
    double a[201][201];
    int main()
    {
        int n,i,j,k,val,flag=0;
        cin>>n;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n+1;j++)
            {
                cin>>a[i][j];
            }
        }
        for(i=1;i<=n;i++)//枚举列
        {
            val=i;
            for(j=i+1;j<=n;j++)
            {
                if(fabs(a[j][i])-fabs(a[val][i])>=eps)//选出该列最大系数
                {
                    val=j;
                }
            }
            for(j=1;j<=n+1;j++)//将第i行与第val行交换
            {
                swap(a[i][j],a[val][j]);
            }
            if(a[i][i]==0)//若最大值为0,说明该列都为0,即无实数解
            {
                flag=1;
                cout<<"No Solution"<<endl;
                break;
            }
            else
            {
                for(j=1;j<=n;j++)
                {
                    if(j!=i)//特判主元这一项
                    {
                        for(k=i+1;k<=n+1;k++)
                        {
                            a[j][k]-=a[i][k]*a[j][i]/a[i][i];//消去其他方程的x[i]的系数
                        }
                    }
                }
            }
        }
        if(flag==0)
        {
            for(i=1;i<=n;i++)//消去系数
            {
                printf("%.2lf\n",a[i][n+1]/a[i][i]);
            }
        }
        return 0;
    }
    
    const double eps=1e-12;
    double a[101][101];
    int main()
    {
        int n,i,j,k,val,flag=1;
        cin>>n;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n+1;j++)
            {
                cin>>a[i][j];
            }
        }
        for(i=1;i<=n;i++)
        {
            val=i;
            for(j=1;j<=n;j++)//上题中是从i开始枚举的,有用式子的仅有i之后的,系数为0直接break,因为只需要判断是否有解
            //但是本题需要判断是否有解,有无数解,所以需要在系数为0后继续算下去,所以有用的式子不仅是i之后的式子,还有i之前且系数为0的式子
            {
                if(!(i>j&&fabs(a[j][j])!=0))
                {
                    if(fabs(a[j][i])-fabs(a[val][i])>=eps)
                    {
                        val=j;
                    }
                }
            }
            for(j=1;j<=n+1;j++)
            {
                swap(a[i][j],a[val][j]);
            }
            if(a[i][i]!=0)
            {
                for(j=1;j<=n;j++)
                {
                    if(j!=i)
                    {
                        for(k=i+1;k<=n+1;k++)
                        {
                            a[j][k]-=a[i][k]*a[j][i]/a[i][i];
                        }
                    }
                }
            }
        }
        for(i=1;i<=n;i++)	
        {
            if(a[i][i]==0)
            {
                if(a[i][n+1]!=0)//无解比无数解优先级更高
                {
                    flag=-1;
                    break;
                }
                else
                {
                    flag=0;
                }
            }
        }
        if(flag==1)
        {
            for(i=1;i<=n;i++)
            {
                printf("x%d=%.2lf\n",i,a[i][n+1]/a[i][i]);
            }
        }
        else
        {
            cout<<flag<<endl;
        }
        return 0;
    }
    

标签:系数,方程组,数论,线性方程组,矩阵,笔记,非零,高斯消
From: https://www.cnblogs.com/The-Shadow-Dragon/p/17644605.html

相关文章

  • 点分树(动态点分治) 学习笔记
    模板题题目传送门给定一棵树(带点权),支持以下操作:修改点权。查询到一个点距离\(\lek\)的点的权值和。\(n,T\le10^5\)算法解析前置知识:点分治我们考虑把每次求出的重心和上一层的重心连边,我们就可以得到点分树。这棵树有以下性质:树高为\(\logn\),也就是暴力找LCA的......
  • MHATC系统笔记3
    Tip:1、NetRecord;参考链接:linux系统UDP丢包问题分析思路|CizixsWriteHere如何高效定位网络丢包问题?-知乎(zhihu.com)【翻译】理解TCP/IP网络栈|CizixsWriteHere1、tcpdump抓的包来自哪?内核TCPchecksum是网卡计算的,不是内核;如果有网络抓包工具(比如wireshark或......
  • 《Java编程思想第四版》学习笔记17
    崩溃JavaJava标准集合里包含了toString()方法,所以它们能生成自己的String表达方式,包括它们容纳的对象。例如在Vector中,toString()会在Vector的各个元素中步进和遍历,并为每个元素调用toString()。假定我们现在想打印出自己类的地址。看起来似乎简单地引用this即可(特别......
  • 我反对独立开发者做笔记产品:从商业角度看笔记产品市场竞争
    事情是这样的,刷掘金时看到这篇文章:良言难劝该死鬼,居然有人觉得独立开发做三件套是件好事,这篇文章提到了另一篇文章,是我很喜欢的一个公众号号主和菜头写的一篇《从番茄时钟和记账本开始》;之前在v2ex也看过相关讨论,于是打算好好思考下这件事情,于是在作者的文章下详细写了评价,一写写......
  • 学习笔记 - Java 面向对象_中
    this关键字当形参名和属性名相同时,使用this关键字来区分,有this修饰的变量是属性,无this修饰的是形参。this可以调用的除了属性,还有方法、构造器。所以,this指的是当前对象(在方法调用时)或当前正在创建的对象(在构造器中调用时)。在构造器中,使用this(形参列表);可以调用......
  • 笔记本电脑主板的细微伤痕:一场与微观世界的舞蹈
    引言:微小的伤痕,巨大的影响有一天,我在检查一台笔记本电脑时,发现了一个微小的细节——主板上的绝缘层有一点被磨损了。这样一个微不足道的伤口,竟然引领了我走入了一个丰富多彩的微观世界。第一幕:一个小小的问题,隐藏的危机伤口的解剖学:细微的危险在我们的笔记本电脑的主板(Motherb......
  • CSS笔记-盒子模型
    CSS笔记-盒子模型1.盒子模型css开发中,常常会提到一个词叫做“盒子”,这里的盒子专业名词叫“盒子模型(BoxModel)”,这一术语是从来设计和布局时使用的。通俗的讲,所有的HTML元素都可以看做是一个盒子;那么,将页面中所有的元素都设置成一个矩形的盒子后,对页面的布局就可以理解成把不......
  • Hadoop学习笔记、知识点搭建速过、包含Hadoop集群搭建、HDFS、IDE操作hadoop,DFSShell
    大数据概述......
  • 操作系统学习笔记
    Stanford:CS140使用操作系统概念CS162使用操作系统:设计与原理基础操作系统发展史原始操作系统在原始操作系统中,程序更多的是与硬件进行绑定,是一个无保护的标准服务库(为了方便用户或开发者使用而提供的一系列标准服务、函数或API)。系统一次只能运行一个程序多任务处理......
  • c++ 丢失笔记 [运算符重载、this指针、复制与拷贝构造、生存周期、箭头操作符]
    运算符重载、this指针、复制与拷贝构造、生存周期、箭头操作符有一部分是学校的OJ里做题需要就提前学了,然后没记笔记,有一部分是笔记丢了。不打算补这些笔记。不过还是在这里mark一下++运算符的重载。因为++运算符可以前置也可以后置,所以这里需要注意一下,如果是后置++,需要一个in......