高斯消元 & 线性基【学习笔记】
高斯消元 & 线性基
本来说不写了,但还是写点吧
[update 2017-02-18]现在发现真的有好多需要思考的地方,网上很多代码感觉都是错误的,虽然题目通过了
[update 2017-02-19]加入线性基
[update 2017-03-31]完善内容,改用markdown
Gauss Elimination
高斯消元(Gaussian elimination)是求解线性方程组的一种算法,它也可用来求矩阵的秩,以及求可逆方阵的逆矩阵。
它通过逐步消除未知数来将原始线性系统转化为另一个更简单的等价的系统。
它的实质是通过初等行变化(Elementary row operations),将线性方程组的增广矩阵转化为行阶梯矩阵(row echelon form)。
概念
增广矩阵
- 系数矩阵右面加上一列常数
矩阵的初等行变换
- 交换两行
- 给一行乘上一个非零数
- 把一行的倍数加到另一行上
主元
从1到n枚举变量作为主元(需要选择这个变量系数绝对值最大的行保证数值稳定性,异或方程、同余方程选非0就可以)
和单纯形法类似,主元要写到等式的一边然后用这个方程替换其他方程中的主元,实现上是用矩阵的初等行变换做加减消元
自由元
枚举到一个变量,如果剩下的行中这个变量的系数都为0,这个变量就是自由元。
自由元存在说明有的方程是线性相关的,加减消元后有的方程就被消掉了。
自由元的值一旦确定,其他变元的值就确定了
自由元数目是一定的,就是消元结束后全0方程的数目(注意矛盾方程消元后常数项不为0)。
自由元集合不一定,但只要枚举一个自由元集合的所有取值就可以得到整个方程组的所有变量取值啦。
关键元
- 每一行的第一个非零元
- 通常来讲这个第i行的关键元应该是第i个。否则说明前面及自己中有自由元。
- 实现上记录pivot[i]为以变元i为关键元的方程在哪一行,也就是变元i用到了哪一行
解线性方程组
过程:
- 消元,不断把系数矩阵变成\(REF\)(阶梯型矩阵)
- 消元之后回代之前就可以进行无解和多解的判断
- 唯一解形成上三角矩阵,回代即可
实现:
完整的判断多解和无解的版本请见POJ2947
bool Gauss(Matrix a, int n) {
for(int i=1; i<=n; i++) {
int r=i;
for(int j=i+1; j<=n; j++)
if(abs(a[j][i]) > abs(a[r][i])) r=j;
if(abs(a[r][i])<eps) return false;
if(r!=i) for(int j=1; j<=n+1; j++) swap(a[r][j], a[i][j]);
for(int j=i+1; j<=n; j++) {
double t = a[j][i]/a[i][i];
for(int k=i; k<=n+1; k++) a[j][k] -= t*a[i][k];
}
}
for(int i=n; i>=1; i--) {
for(int j=n; j>i; j--) a[i][n+1] -= a[i][j]*a[j][n+1];
a[i][n+1] /= a[i][i];
}
return true;
}
解XOR方程组
过程
设N个未知数,M个方程,A为系数矩阵
\(now\)表示当前到了哪一行
$now\ =\ 1 $
\(for\ i\ =\ 1\ to\ N\)
若存在\(j\ \ge\ now\)使得\(A_{j\ ,\ i}\)为\(1\)则
交换第\(j\)行与第\(now\)行
用第\(now\)行对之后的行进行消元
\(now\ +=\ 1\)
否则第\(i\)个变量是自由变量,\(now\)不变
实现
可以使用bitset压位+高斯约当消元
高斯约当消元是选主元之后将主元化为1(xor方程不需要),然后枚举除主元所在行之外所有行消元,可以发现一个过程之后主元所在列就是单位矩阵(对角矩阵)的形式,所以最后不用回代。
void Gauss(bitset<N> a[N], int n) {
now=1;
for(int i=1; i<=n; i++) {
int j=now;
while(j<=n && !a[j][i]) j++;
if(j==n+1) continue;
if(j!=now) swap(a[now], a[j]);
for(int k=1; k<=n; k++)
if(k!=now && a[k][i]) a[k]^=a[now];
now++;
}
now--;
}
解的判断
无解
- 存在矛盾方程,消元后系数全为\(0\),常数项不为\(0\)
多解
- 出现了\(S\)个自由元,这些变量可任意取值从而确定其余变量的值\(2^S\)组解
- 实现上,now<n说明出现自由元,并且自由元所在方程一定在最后几行。求最优解需要枚举自由元的取值然后回代
唯一解
- 无自由元,即now=n,形成上三角矩阵
对于高斯约当消元
系数矩阵变成了对角矩阵
如果存在自由元,那么大约张这样
O....O
........#...O
...................O
空行
# 位置是一个自由元
这时候也需要枚举自由元的取值然后回代
求矩阵的逆
这里说一种方法,对A进行高斯约当消元,右面的常数列换成单位矩阵。校园后,左面变成了单位矩阵,右面就是\(A^{-1}\)
Matrix inverse(Matrix a) {
Matrix c; c.im();
for(int i=1; i<=n; i++) {
int r;
for(r=i; r<=n; r++) if(a[r][i]) break;
// r != n+1
if(r!=i) for(int j=1; j<=n; j++)
swap(a[i][j], a[r][j]), swap(c[i][j], c[r][j]);
ll inv = Pow(a[i][i], P-2);
for(int j=1; j<=n; j++)
a[i][j] = a[i][j]*inv%P, c[i][j] = c[i][j]*inv%P;
for(int k=1; k<=n; k++) if(k!=i) {
ll t = a[k][i]%P;
for(int j=1; j<=n; j++)
mod(a[k][j] -= a[i][j]*t%P), mod(c[k][j] -= c[i][j]*t%P);
}
}
return c;
}
线性基
概念
线性空间:
设\(V\)是一个向量集合
\(\forall a,b\ \in V\quad a+b \in V\)
\(\forall a\in V,\ k \in F\quad ka\in V\)
线性组合:
线性空间\(V\)的子集\(S=\{ v_1,v_2,...,v_n \}\),对于一个\(V\)中的元素\(v\),存在一组系数使得
\]
那么\(v\)是\(S\)的一个线性组合
线性相关:
线性空间\(V\)的子集\(S=\{ v_1,v_2,...,v_n \}\),如果有一组系数使得
\(a_1v_1+a_2v_2+...+a_nv_n=0\)
则称S是线性相关的
也就是说\(S\)中的某个向量能被自己所表示出来
线性基:
和小新讲的向量的基底好像啊(就是一个东西吧)
\(V\)中的任意一个向量都能唯一的表示成\(S\)中向量的线性组合,那么\(S\)是\(V\)的一组基
线性基是满足线性无关的极大子集
线性基中元素的个数(基数)一定,就是线性空间的维度
任一线性无关组的子集线性无关
我们可以用一组向量\(S\)(不一定线性无关)来构造线性空间,称为\(span(S)\)
矩阵的秩
矩阵可以看成一个向量组,线性基对应着矩阵的秩
矩阵的行秩等于列秩
\(行列式不为0 \Leftrightarrow 满秩 \Leftrightarrow 向量线性无关\)
可以使用高斯消元求矩阵(横向量组)的秩(线性基)
拟阵
类似最小生成树
线性无关子集构成一个拟阵,可以用贪心求最大权线性基
异或问题
把每个二进制位看成一个维度,每个整数就是一个向量,向量之间的运算是异或,一个整数的集合就是一个线性空间
插入
用p[i]保存线性基里第i个数位为1的向量(数字)(类似于高斯消元里的每个主元用到哪一行)
待插入x,从高位到低位枚举x为1的二进制位i,如果有p[i]了那么异或p[i]消去x这一位的1,如果没有p[i]那么p[i]=x并推出
如果x最后不是0说明插入成功,否则说明x和已经插入的数字线性相关
注意插入结束后,保证数字p[i]在第i位为1且之后的数字第i位都不是1,不保证在p[i]之前插入的数字第i位不是1,所以在这种线性基上求最大值不能直接异或上要取max
这样可以配合贪心求最大权线性基
合并
将一个全部插入另一个就好了
构造
异或高斯消元后形成对角矩阵,每一位只有一个数字是1
这时候有now个位可以是1,最多有\(2^{now}\)种取值,第i行a[i]保存了第i大的可以是1的二进制位的值
利用构造后的线性基可以求线性空间的最大值,最小值,k小值
- 异或所有a[i]
- a[now],严格次大值就是a[i]^a[now]
- 对k二进制拆分,第i位为1异或上则异或上a[now-i]
高斯消元 & 线性基【学习笔记】的更多相关文章
- 洛谷P3389 高斯消元 / 高斯消元+线性基学习笔记
高斯消元 其实开始只是想搞下线性基,,,后来发现线性基和高斯消元的关系挺密切就一块儿在这儿写了好了QwQ 先港高斯消元趴? 这个算法并不难理解啊?就会矩阵运算就过去了鸭,,, 算了都专门为此写个题解还 ...
- HDU 3949:XOR(高斯消元+线性基)
题目链接 题意 给出n个数,问这些数的某些数xor后第k小的是谁. 思路 高斯消元求线性基. 学习地址 把每个数都拆成二进制,然后进行高斯消元,如果这个数字这一位(列)有1,那么让其他数都去异或它,消 ...
- BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基
[题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i ...
- BZOJ 4004 JLOI2015 装备购买 高斯消元+线性基
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4004 Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装 ...
- 【BZOJ-4269】再见Xor 高斯消元 + 线性基
4269: 再见Xor Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 131 Solved: 81[Submit][Status][Discuss] ...
- BZOJ 4269: 再见Xor [高斯消元 线性基]
4269: 再见Xor Description 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. 我太愚蠢了连数组开小了以及$2^{ ...
- BZOJ 2844 高斯消元 线性基
思路: //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using ...
- HDU 3949 XOR(高斯消元搞基)
HDU 3949 XOR pid=3949" target="_blank" style="">题目链接 题意:给定一些数字,问任取几个异或值第 ...
- [JLOI2015]装备购买 题解 / 实数线性基学习笔记
题目链接 看这道题之前,以为线性基只是支持异或的操作... 那么,我认为这道题体现出了线性基的本质: 就是说如何用最小的一个集合去表示所有出现的装备. 我们假设已经会使用线性基了,那么对于这道题该怎么 ...
随机推荐
- Redis介绍及Jedis测试
1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes ...
- 96、python version 3.6 required,which was not fount in the registry(python3.6安装scrapy)
在安装scrapy时遇到问题 环境:win10(64位), Python3.6(64位) 安装scrapy: 1.安装wheel(安装后,便支持通过wheel文件安装软件) pip3 install ...
- jquery1.8 在IE8 下面报错:对象不支持此属性或方法 return b.getAttribute("id")===a
jquery1.8 在IE8 下面报错: 对象不支持此属性或方法 调试发现是下面这一行报错: 在IE8下面报错,在chrome和firefox都是好的. 实在找不到原因,最后把源码改成下面这样: 没有 ...
- html button 点击链接
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 怎么去掉织梦网站首页带的index.html/index.php
方法1. 1)在空间面板里面找到默认首页设置: 我们是需要去掉index.html,这时我们只需要把index.html这个把它移到最顶级去就行,然后点击确定,在打开网站刷新下,就基本可以解决了! 其 ...
- Eclipse版本
Eclipse 3.1 IO 木卫一,伊奥 2005Eclipse 3.2 Callisto 木卫四,卡里斯托 2006Eclipse ...
- ngRx 官方示例分析 - 4.pages
Page 中通过构造函数注入 Store,基于 Store 进行数据操作. 注意 Component 使用了 changeDetection: ChangeDetectionStrategy.OnPu ...
- ADO.NET复习总结(6)-断开式数据操作
一.基础知识 主要类及成员(和数据库无关的)(1)类DataSet:数据集,对应着库,属性Tables表示所有的表(2)类DataTable:数据表,对应着表,属性Rows表示所有的行(3)类Data ...
- ADO.NET复习总结(5)--工具类SqlHelper 实现登录
工具类SqlHelper 即:完成常用数据库操作的代码封装 一.基础知识1.每次进行操作时,不变的代码: (1)连接字符串:(2)往集合存值:(3)创建连接对象.命令对象:(4)打开连接:(5)执行命 ...
- 【视频编解码·学习笔记】2. H.264简介
一.H.264视频编码标准 H.264视频编码标准是ITU-T与MPEG合作产生的又一巨大成果,自颁布之日起就在业界产生了巨大影响.严格地讲,H.264标准是属于MPEG-4家族的一部分,即MPEG- ...