zoukankan      html  css  js  c++  java
  • 高斯消元模板

    高斯消元:

    事实上就是用矩阵初等变换解线性方程组,仅仅是他要求每次选取的主元一定要是最大值。

    模板

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    using namespace std;
    const int MAXN=10000;
    int a[MAXN][MAXN];//增广矩阵
    int x[MAXN];//解集
    bool free_x[MAXN];//标记是否是不确定的变元
    int gcd(int a,int b)
    {//最大公约数
        int t;
        while(b!=0)
        {
            t=b;
            b=a%b;
            a=t;
        }
        return a;
    }
    int lcm(int a,int b)
    {//求最小公倍数
        return a/gcd(a,b)*b;//先除后乘防溢出
    }
    int Gauss(int equ,int var)
    {
        int i,j,k;
        int max_r;// 当前这列绝对值最大的行.
        int col;//当前处理的列
        int ta,tb;
        int LCM,temp,free_x_num,free_index;
        for(int i=0; i<=var; i++)
        {
            //初始化
            x[i]=0;
            free_x[i]=true;
        }
    //转换为行阶梯阵.
        col=0; // 当前处理的列  k为当前处理的行
        for(k = 0; k < equ && col < var; k++,col++)
        {
            //最后一列没有化解
    //找到该col列元素绝对值最大的那行与第k行交换(为了在除法时减小误差)
            max_r=k;
            for(i=k+1; i<equ; i++)
            {
                if(abs(a[i][col])>abs(a[max_r][col]))
                    max_r=i;
            }
            if(max_r!=k)
            {
                //与第k行交换.
                for(j=k; j<var+1; j++)
                    swap(a[k][j],a[max_r][j]);
            }
            if(a[k][col]==0)
            {
    //说明该col列第k行下面全是0了,则处理当前行的下一列.
                k--;
                continue;
            }
            for(i=k+1; i<equ; i++)
            {
                // 利用主元消元
                if(a[i][col]!=0)
                {
                    LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                    ta = LCM/abs(a[i][col]);
                    tb = LCM/abs(a[k][col]);
                    if(a[i][col]*a[k][col]<0)
                        tb=-tb;//异号的情况是相加
                    for(j=col; j<var+1; j++)
                        a[i][j] = a[i][j]*ta-a[k][j]*tb;
                }
            }
        }
    // 1. 无解的情况有:0=d;
        for (i = k; i < equ; i++)
            if (a[i][col] != 0) return -1;
    // 2. 无穷解的情况
        if (k < var)
        {
            //var是未知元个数。首先,自由变元有var - k个
            for (i = k - 1; i >= 0; i--)
            {
                free_x_num = 0;
                for (j = 0; j < var; j++)
                    if (a[i][j] != 0 && free_x[j])
                        free_x_num++;
                free_index = j;
                if (free_x_num > 1) continue;
    // 无法求解出确定的变元.
    // 说明就仅仅有一个不确定的变元free_index。那么能够求解出该变元,且该变元是确定的.
                temp = a[i][var];
                for (j = 0; j < var; j++)
                {
                    //找已经求出的未知元
                    if (a[i][j] != 0 && j != free_index)
                        temp -= a[i][j] * x[j];//移项
                }// 求出该变元.
                x[free_index] = temp / a[i][free_index];
                free_x[free_index] = 0; // 该变元是确定的.
            }
            return var - k; // 自由变元有var - k个.
        }
    // 唯一解的情况:在var*(var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
        for (i=var-1; i>=0; i--)
        {
            temp=a[i][var];
            for (j = i + 1; j < var; j++)
            {
                if (a[i][j] != 0) temp -= a[i][j] * x[j];
            }
            if (temp % a[i][i] != 0)
                return -2; // 说明有浮点数解,但无整数解.
            x[i] = temp / a[i][i];
        }
        return 0;
    }
    int main()
    {
        int i, j;
        int equ,var;//行,列
        while (scanf("%d %d", &equ, &var) != EOF)
        {
            memset(a, 0, sizeof(a));
            for (i = 0; i < equ; i++)
            {
                for (j = 0; j < var + 1; j++)
                {
                    //增广矩阵
                    scanf("%d", &a[i][j]);
                }
            }
            int free_num = Gauss(equ,var);
        }
        return 0;
    }
    
    





  • 相关阅读:
    快速创建MockAPI
    Eolinker SaaS 7.5 版本更新
    【翻译】几个优质的REST API工具
    建立RESTful API测试程序的基础
    Ubuntu下gcc安装及使用
    c++转化成delphi的代码
    VCL组件的属性和方法详解
    Delphi组件开发教程指南目录
    FASM 第一章 简介
    (一)SQL 基础知识
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6880073.html
Copyright © 2011-2022 走看看