离散数学笔记(集合论)+Warshall算法实现传递关系闭包

花了两天多的时间看了集合论的大部分内容,主要还是在了解定义定理和证明,练的题还不够,以后有时间还得练习巩固。很多问题还是一知半解的,还是得开学认真听课做题吧,有很多总结得不清楚的,见谅~

今天来码一遍Warshall算法,首先来回顾一下:
考虑一个n+1个矩阵序列M0,M1…Mn,将矩阵Mk的第I行j列的元素记为Mk[i,j],对于k=0,1,2…n Mk[i,j]=1当且仅当在R的关系图存在一条vi到vj的路径,并且这条路径除端点外中间只经过{v1,v2,…vk}中的结点,而M0是R的关系矩阵,Mn对应R的传递闭包。Warshall算法从M0开始顺序计算直到Mn为止。
假设Mk已经计算完毕,接下来需要计算Mk+1,对于每一组i,j确定Mk+1[I,j]是否为1,等于1当且仅当在R的关系图中存在一条从vi到vj并且中间只经过{v1,v2…vk+1}的路径,这种路径分两类:
第一类:只经过{v1,v2…vk}这时Mk[ij]=1
第二类:经过了vk+1的路径,因为回路可从路径中删除,考虑经过vk+1一次的路径,这条路径可分成两段,从xi到xk+1再从xk+1到xj,有Mk[i,k+1]=1,Mk[k+1,j]=1。
即让Mk[I,k+1]=1 ^ Mk[k+1,j]=1为真就行了
把两类情况并起来,就组成了算法的核心部分

上代码:

#include<iostream>
int i,j,k,n;
int matrix[100][100];
void PaintMatrix()
{
 std::cout<<"------------"<<std::endl;
 for(int m=1;m<=n;m++)
 {
  for(int t=1;t<=n;t++)
  {
   std::cout<<matrix[m][t]<<" ";
  }
  std::cout<<std::endl;
 }
}
int main()
{
 //std::cout<<"please input number"<<std::endl;
 std::cin>>n;
 //std::cout<<"input matrix"<<std::endl;
 for(int a=1;a<=n;a++)
 {
  for(int b=1;b<=n;b++)
  {
   std::cin>>matrix[a][b];
  }
 }
 //warshall
 for(k=1;k<=n;k++)
 { 
  for(i=1;i<=n;i++)
  {
   for(j=1;j<=n;j++)
   {
    matrix[i][j]=matrix[i][j]|(matrix[i][k]&matrix[k][j]);
   }
  }
  PaintMatrix();
 }
} 

了解了原理实现起来就很简单了,把书上例题运行结果贴上来感受一下

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
附上其他学习笔记内容

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值