离散数学实验报告2

文章目录

  • 离散数学实验报告2
    • 一、实验题目
    • 二、实验目的
    • 三、实验要求
    • 四、实验步骤和内容
      • 需求分析:
        • 输入形式与输入范围
      • 概要设计:
        • 使用的数据结构与算法:
        • 程序流程:
      • 详细代码
      • 调试分析
        • 调试过程中所遇到的问题及解决方法
        • 算法的时空分析
    • 五、实验结果
    • 六、实验总结

一、实验题目

实验题目:关联矩阵、相邻矩阵、生成树、环路空间、断集空间的求解

实验时间: 2021.12.16

二、实验目的

  1. 掌握无向连通图生成树的求解方法;

  2. 掌握基本回路系统和环路空间的求解方法;

  3. 掌握基本割集系统和断集空间的求解方法;

  4. 了解生成树、环路空间和断集空间的实际应用。

三、实验要求

  1. 给定无向简单连通图的相邻矩阵 例如:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MPyNdYqm-1654332805884)(/Users/a26012/Desktop/截屏2021-12-23 15.02.35.png)]。
  2. 输出此图的关联矩阵M
  3. 求此图所有生成树个数。
  4. 输出其中任意一颗生成树的相邻矩阵(默认第i行对应顶点vi)和关联矩阵(默认第i行对应顶点vi,第j列对应边ej)。
  5. 求此生成树对应的基本回路系统(输出形式如:{e1e4e3,e2e5e3})。
  6. 求此生成树对应的环路空间(输出形式如:{Φ,e1e4e3,e2e5e3,e1e4e5e2})。
  7. 求此生成树对应的基本割集系统(输出形式如:{{e1,e4},{e2,e5},{e3,e4,e5}})。
  8. 求此生成树对应的断集空间(输出形式如:{Φ, {e1,e4}, {e2,e5}, {e3,e4,e5}, {e1,e2,e4,e5}, {e1,e3,e5}, {e2,e3,e4}, {e1,e2,e3}})。

四、实验步骤和内容

需求分析:

给定相邻矩阵,求关联矩阵,生成树个数,输出其中任意一颗生成树的相邻矩阵和关联矩阵。

求此生成树对应的基本回路系统,环路空间

求此生成树对应的基本割集系统,断集空间

输入形式与输入范围

预设输入点范围 : 0 < n < 999 0<n<999 0<n<999

邻接矩阵的边数: 0 < m < 99 9 2 0<m<999^2 0<m<9992

输入形式: 相邻矩阵 如:

0 1 1 0 1
1 0 1 0 1
1 1 0 1 0
0 0 1 0 1
1 1 0 1 0

输出

示例:

0 1 1 0 1
1 0 1 0 1
1 1 0 1 0
0 0 1 0 1
1 1 0 1 0e1 e2 e3 e4 e5 e6 e7
v1 1  1  1  0  0  0  0
v2 1  0  0  1  1  0  0
v3 0  1  0  1  0  1  0
v4 0  0  0  0  0  1  1
v5 0  0  1  0  1  0  1  生成树的个数为:24它的一棵树为:V1 V2 V3 V4 V5
V1  0  1  1  0  1
V2  1  0  0  0  0
V3  1  0  0  1  0
V4  0  0  1  0  0
V5  1  0  0  0  0 e1 e2 e3 e4
v1 1  1  1  0
v2 1  0  0  0
v3 0  1  0  1
v4 0  0  0  1
v5 0  0  1  0  基本回路系统:{e4e2e1, e5e3e1, e7e3e2e6, }
环路空间:{ Φ,e1e2e4,e1e3e5,e2e3e6e7,e2e3e4e5,e1e3e4e6e7,e1e2e5e6e7,e4e5e6e7,}基本割集系统:{e4e5e1,e4e5e7e2,e4e5e7e3,e4e5e7e6,}
断集空间{ Φ,e1e4e5,e2e4e5e7,e3e4e5e7,e4e5e6e7,e1e2e7,e1e3e7,e1e6e7,e2e3,e2e6,e3e6,e1e2e3e4e5,e1e2e4e5e6,e1e3e4e5e6,e2e3e4e5e6e7,e1e2e3e6e7,}

概要设计:

使用的数据结构与算法:

关联矩阵、相邻矩阵、广度优先遍历、深度优先遍历、矩阵树定理(Matrix-Tree 定理)求生成树个数、分治思想

程序流程:

  1. 读入相邻矩阵
  2. 根据相邻矩阵,求出邻接矩阵sq2,基尔霍夫矩阵K。
  3. 输出邻接矩阵
  4. 根据基尔霍夫矩阵和矩阵树定理求出生成树个数gauss( )。
  5. printTree( )函数中用广度优先遍历求出生成树,xl为树的相邻矩阵 ,gl为树的邻接矩阵
  6. 求基本回路系统和环路空间printSystem()。求基本回路系统方法:枚举每一条弦,如果把它加到树中,就会有且只有一条回路,该回路就是一条基本回路。求环路空间方法,深度优先搜索,枚举所有情况,进行对称差运算。
  7. 求基本割集系统,断集空间printSystem2()。求基本割集系统:枚举每一条树枝,找到该树枝对应的边割集,该割集就是一个基本割集。求断集空间方法,同上,深度优先搜索,枚举所有情况,进行对称差运算。

详细代码

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <vector>
#include <queue>
using namespace std;
int sq[1000][1000];    //相邻矩阵
int sq2[1000][10000],edx=0,eedx=0;   //邻接矩阵
int edge[1000][1000];    //边编号
int c[1000][1000];
int xl[1000][1000];    //树的相邻矩阵
int gl[1000][1000];   //树的邻接矩阵
bool st[1000];     //是否遍历到
int wsz[1000];  //方便计算对称差
int K[1000][1000];  //生成树个数
vector<vector<int>> baseC;   //基本回路系统
vector<vector<int>> baseG;   //基本割集系统
int sz=0;
const int MOD = 0x3f3f3f3f;
int gauss(int n) {//求矩阵K的n-1阶顺序主子式int res = 1;for (int i = 1; i <= n - 1; i++) {//枚举主对角线上第i个元素for (int j = i + 1; j <= n - 1; j++) {//枚举剩下的行while (K[j][i]) {//辗转相除int t = K[i][i] / K[j][i];for (int k = i; k <= n - 1; k++)//转为倒三角K[i][k] = (K[i][k] - t * K[j][k] + MOD) % MOD;swap(K[i], K[j]);//交换i、j两行res = -res;//取负}}res = (res * K[i][i]) % MOD;}return (res + MOD) % MOD;
}void print_sq(){cout<<"  ";for(int i=1;i<=edx;i++){cout<<"e"<<i<<" ";}cout<<endl;for(int i=1;i<=sz;i++){cout<<"v"<<i<<" ";for(int j=1;j<=edx;j++){if(sq2[i][j]) cout<<1;else cout<<0;cout<<"  ";}cout<<endl;}
}void printTree(){bool st[1000];memset(xl,0,sizeof xl);memset(st,0,sizeof st);memset(gl,0,sizeof gl);queue<int> Q;Q.push(1);st[1]= true;while(!Q.empty()){int nw=Q.front();Q.pop();for(int i=1;i<=sz;i++){if(!st[i]&&sq[nw][i]){xl[nw][i]=xl[i][nw]=1;Q.push(i);st[i]= true;}}}cout<<"\n它的一棵树为:\n";printf("   ");for(int i=1;i<=sz;i++){printf("V%d ",i);}cout<<endl;for(int i=1;i<=sz;i++){printf("V%d ",i);for(int j=1;j<=sz;j++){printf(" %d ",xl[i][j]);}cout<<endl;}cout<<endl;edx=0;for(int i=1;i<=sz;i++){for(int j=i+1;j<=sz;j++){if(xl[i][j]){++edx;gl[i][edx]=gl[j][edx]=1;}}}cout<<"  ";for(int i=1;i<=edx;i++){cout<<"e"<<i<<" ";}cout<<endl;for(int i=1;i<=sz;i++){cout<<"v"<<i<<" ";for(int j=1;j<=edx;j++){if(gl[i][j]) cout<<1;else cout<<0;cout<<"  ";}cout<<endl;}
}
void bfs(int x,int y){queue<int> Q;vector<int> tmp;bool st[1000];int fa[1000];memset(fa,0,sizeof fa);memset(st,0,sizeof st);Q.push(x);st[x]= true;fa[x]=-1;tmp.push_back(edge[x][y]);while(!Q.empty()){int nw=Q.front();Q.pop();for(int i=1;i<=sz;i++){if(!st[i]&&xl[nw][i]){xl[nw][i]=xl[i][nw]=1;Q.push(i);fa[i]=nw;st[i]= true;}}if(st[y]) break;}int nw=y;while(nw!=x){tmp.push_back(edge[nw][fa[nw]]);cout<<"e"<<edge[nw][fa[nw]];nw=fa[nw];}baseC.push_back(tmp);
}
void dfs(int nub,int idx,int type){      //枚举对称差if(nub==0){for(int i=1;i<=eedx;i++){if(wsz[i]%2)cout<<"e"<<i;}cout<<",";return;}if(idx==baseC.size()&&type==1) return;if(idx==baseG.size()&&type!=1) return;if(type==1){for(int j=0;j< baseC[idx].size() ;j++)  wsz[ baseC[idx][j] ]++;dfs(nub-1,idx+1,1);    //选第idx个基本回路for(int j=0;j<baseC[idx].size();j++)  wsz[baseC[idx][j]]--;dfs(nub,idx+1,1);}else{for(int j=0;j<baseG[idx].size();j++)  wsz[baseG[idx][j]]++;dfs(nub-1,idx+1,2);for(int j=0;j<baseG[idx].size();j++)  wsz[baseG[idx][j]]--;dfs(nub,idx+1,2);}
}
void printSystem(){int base=0;cout<<"\n基本回路系统:{";for(int i=1;i<=sz;i++){for(int j=i+1;j<=sz;j++){if(sq[i][j]&&!xl[i][j]){cout<<"e"<<edge[i][j];bfs(i,j); //2 4 / 3 4cout<<", ";base++;}}}memset(wsz,0,sizeof wsz);cout<<"}\n环路空间:{ Φ,";for(int i=1;i<=baseC.size();i++){dfs(i,0,1);}cout<<"}\n";
}
void gogo(int x){if(st[x]) return;st[x]= true;for(int i=1;i<=sz;i++){if(sq[x][i]) gogo(i);}
}
vector<int> tmp;
bool wzy(int n){if(n==0){for(int i=0;i<=sz;i++) st[i]=0;gogo(1);for(int i=1;i<=sz;i++)if(!st[i]){baseG.push_back(tmp);return true;}return false;}for(int i=1;i<=sz;i++){for(int j=i+1;j<=sz;j++){if(sq[i][j]&&!xl[i][j]){sq[i][j]=sq[j][i]=0;tmp.push_back(edge[i][j]);bool rt=wzy(n-1);tmp.pop_back();sq[i][j]=sq[j][i]=1;return rt;}}}
}
void printSystem2(){int base=0;cout<<"\n基本割集系统:{";for(int i=1;i<=sz;i++){for(int j=i+1;j<=sz;j++){if(xl[i][j]){sq[j][i]=sq[i][j]=0;tmp.clear();for(int k=1;;k++){if(wzy(k)){break;}}baseG[baseG.size()-1].push_back(edge[i][j]);sq[j][i]=sq[i][j]=1;}}}for(int i=0;i<baseG.size();i++){for(int j=0;j<baseG[i].size();j++){cout<<"e"<<baseG[i][j];}cout<<",";}cout<<"}\n断集空间{ Φ,";memset(wsz,0,sizeof wsz);for(int i=1;i<=baseG.size();i++){dfs(i,0,2);}cout<<"}\n";
}
int main() {string str;getline(cin,str);while(str!="\0"){stringstream ss(str);sz++;for(int j=1;!ss.eof();j++){ss>>sq[sz][j];}getline(cin,str);}for(int i=1;i<=sz;i++){for(int j=i+1;j<=sz;j++){if(sq[i][j]){++edx;++eedx;edge[i][j]=edge[j][i]=edx;sq2[i][edx]=sq2[j][edx]=1;K[i][i]++;K[j][j]++;K[i][j]--;K[j][i]--;}}}print_sq();cout<<endl<<"生成树的个数为:"<<gauss(sz)<<endl;if(!gauss(sz)) return 0;printTree();printSystem();printSystem2();return 0;
}

调试分析

调试过程中所遇到的问题及解决方法

一切正常

算法的时空分析

求邻接矩阵,基尔霍夫矩阵,求生成树 O ( n 2 ) O(n^2) O(n2)

Matrix-Tree 定理(求矩阵行列式) O ( n 4 ) O(n^4) O(n4)

基本回路系统 O ( n 3 ) O(n^3) O(n3)

基本割集系统 O ( n 4 ) O(n^4) O(n4)

求断集空间,环路空间 O ( 2 n ) O(2^n) O(2n)

五、实验结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7ioy7pe-1654332805884)(/Users/a26012/Desktop/截屏2021-12-23 15.34.55.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0JRu0BA-1654332805885)(/Users/a26012/Desktop/截屏2021-12-23 15.35.15.png)]

六、实验总结

心得体会:

  • 对无向连通图生成树的求解方法,基本回路系统和环路空间的求解方法,基本割集系统和断集空间的求解方法有了更深的理解,了解生成树、环路空间和断集空间的实际应用。很好的锻炼了代码能力,吸收了许多教训,学到了编程中的许多知识,非常有用。
  • 可能是因为这个实验比较难,有一些同学借鉴了我的代码。

离散数学实验2 关联矩阵、相邻矩阵、生成树、环路空间、断集空间的求解 C++相关推荐

  1. 离散数学实验2关联矩阵相邻矩阵

    代码展示 #include <iostream> using namespace std; int XLmatrix[100][100] = { 0 };//输入的相邻矩阵 int n;/ ...

  2. 离散数学实验3 平面图判定及对偶图的求解 C++

    离散数学实验报告3 文章目录 离散数学实验报告3 一.实验题目 二.实验目的 三.实验要求 需求分析: 输入形式与输入范围 概要设计: 使用的数据结构与算法: 程序流程: 详细代码 调试分析 调试过程 ...

  3. 离散数学实验题目-图

    离散数学实验报告 计算机科学与技术系 目录 第一章 实验概述 3 1.1 实验目的 3 1.2 实验内容 3 1.3 实验环境 3 第二章 实验原理和实现过程 4 2.1 实验原理 4 2.2 实验过 ...

  4. 离散数学实验-01 可简单图化,连通图和欧拉图的判断(利用Fleury算法输出欧拉回路)

    离散数学的实验 实验要求 给定一非负整数序列(例如:(4,2,2,2,2)). 判断此非负整数序列是否是可图化的,是否是可简单图化的. 如果是可简单图化的,根据Havel定理过程求出对应的简单图,并输 ...

  5. 离散数学实验题目-关系

    离散数学实验报告 计算机科学与技术系 目录 第一章 实验概述 3 1.1 实验目的 3 1.2 实验内容 3 1.3 实验环境 3 第二章 实验原理和实现过程 4 2.1 实验原理 4 2.2 实验过 ...

  6. 离散实验偏序关系满足实验报告C语言,离散数学实验三:偏序关系中盖住关系的求取及格论中有补格的判定...

    离散数学实验报告 我希望我能骄傲的走下去!大家每天都要开心向上哦! 题目:输入n,求1~n 中的满足整除关系的因子.再根据盖住关系的原理求盖住关系.最后判断是否为有补格.任意输入一个整数作为n 值. ...

  7. 离散数学实验报告四——图的应用

    离散数学实验报告四--图的应用 预习内容: 1.图的基本概念 1.1图的定义:现实世界中许多现象能用某种图形表示,这种图形是由一些点和一些连接两点间的连线所组成. 1.2邻接点: 同一条边的两个端点. ...

  8. 离散数学实验一——关系

    离散数学实验一--关系 一.预习内容: 1.自反性:从给定的关系矩阵来断判关系R是否为自反是很容易的.若M(R的关系矩阵)的主对角线元素均为1,则R是自反关系:若M(R的关系矩阵)的主对角线元素均为0 ...

  9. 离散数学实验报告 实验3 欧拉路的确定

    离散数学实验报告 实验3 欧拉路的确定 一.实验目的 理解欧拉图的概念,掌握欧拉通/回路的判定方法. 二.实验内容 输入一个无向简单图的邻接矩阵,判定该图是否含有欧拉通/回路.若有,请给出一条欧拉通/ ...

最新文章

  1. js如何判断当前页面是否处于激活状态
  2. PAT_B_1003_Java(20分)
  3. MCGS与PLC通讯不上
  4. 经典案例:如何优化Oracle使用DBlink的SQL语句
  5. 程序开发语言c#中的 应该发成什么音,0006. 如何在C# winform 上开发 文字转语音
  6. 浅析MySQL中exists,in ,=的使用
  7. 基于BP神经网络的人口预测
  8. PX4自主设置飞行模式
  9. 微信小程序消息通知-打卡考勤
  10. 制作微信公众号二维码,跳转,获取参数
  11. 小白专属:大数据总纲_大数据路线_高屋建瓴的体验大数据的世界
  12. python协程gevent案例:爬取斗鱼美女图片
  13. 程序员不可不知的版权协议
  14. 计算机网络常见面试题,一网打尽!
  15. 2019年淘宝新店如何引流
  16. css 文字溢出...显示,hover时显示隐藏文字
  17. php 读取 excel 文件并上传数据库
  18. 2020年 ICLR 国际会议最终接受论文(poster-paper)列表(四)
  19. Duplicate entry '1' for key 'PRIMARY'(报错)
  20. Excel实现数据转置,很方便操作

热门文章

  1. java 输出素数_java 素数(按要求输出)
  2. 最齐全的形象墙样机模板素材,速来收藏
  3. 这个MT4指标代码哪里出问题了?
  4. 搞笑的100条脑筋急转弯
  5. @Register指令
  6. matlab fromstream,matlab安装问题求助
  7. 蹄疾步稳,勇毅笃行,小白的大学四年
  8. Linux中IP地址的配置
  9. 尚学堂python培训的前景
  10. mysql workbench8.0关键词大写_Mysql从入门到精通全文整理