Warshell's Algorithms
来源:互联网 发布:网络连接图标是灰色的 编辑:程序博客网 时间:2024/05/22 08:11
学习离散数学的时候遇到了这个算法,此算法用于计算闭包矩阵(closure),其复杂度较普通的直接合并的方法要简单,为O(n^3),以下简单介绍一下这个算法~
(以下介绍传递闭包矩阵,其它类型的矩阵与传递闭包思想一致,且相对简单,大家可以自己写写)
1. 思想
2. 代码实现
i) 我们最初知道的仅仅是集合之间元素的关系,那么我们需要知道这个集合内有几个元素,并将它们赋值。
cout<<"The number of element in your set: "; int size; cin>>size; int mySet[size]; for (int i=0; i<size; i++) { cout<<i+1<<". "; cin>>mySet[i]; }
这个是非常简单的,就不作解释啦。
ii) 接下来,我们通过集合内元素的关系(relation)来生成关系矩阵,它是n*n的。
首先,我们需要user来告诉我们集合内元素的关系,我们需要定义一种表示关系的符号:
以下, 一组关系内部的两个元素用逗号(",")分隔, 关系之间用冒号(":")分隔。描述结束用q来标志结束。
如: 1,3 : 2,5 :3,2: 3,1 q
表示1到3为一组关系,2到5为一组关系(注意3到1与1到3是不同的关系),以此类推。
这是笔者自己定义的,你们可以自己定义。
这里还需要注意和说明几点:
a) 当user输入的关系中的某个元素是原来集合中没有的元素,我们就需要舍弃这组关系。
b) 这里是用new来声明二维数组,原因在于后面将要使用的函数,在后面会再提到。
bool **mat=new bool *[size]; for (int i=0; i<size; i++) { mat[i]=new bool[size]; }
c) 这里是用布尔数组,原因是这是一个0-1数组,后面在运算时也将有所简化。
下面是具体实现:
bool **mat=new bool *[size]; for (int i=0; i<size; i++) { mat[i]=new bool[size]; } //preset the matrix to zero for (int i=0; i<size; i++) { for (int j=0; j<size; j++) mat[i][j]=0; } //transfer relation to relation matrix int temp; char ch=0; int li = 0,ri = 0;//to store the left value and right value in a relation bool leftGood=false,rightGood=false,leftTurn=true;//good: the element exist;turn for left value to store->true int index;//the index of the vl; do { cin>>temp; if (cin.std::__1::ios_base::good()) { if ((index=returnVl(temp, size, mySet))!=-1) {//if the value exist if (leftTurn) { li=index; leftTurn=false; leftGood=true; }else if(leftGood){ ri=index; rightGood=true; leftTurn=true; } }else { if (leftTurn) { leftGood=false; }else { rightGood=false; } } }else { cin.clear(); ch=cin.get(); if (ch!=',') { if (leftGood&&rightGood) { mat[li][ri]=1; leftGood=rightGood=false; } leftTurn=true; } } } while (ch!='q');
用到的检查是否含有该元素的函数定义(有则返回其index,无则返回-1,因为index不可能是-1):
int returnVl(int vl,int size,int *arr){ int i=0; for (i=0; i<size&&vl!=arr[i]; i++) ; if((i!=size)||(arr[size-1]==vl)) { return i; }else return -1;}
iii) 接下来我们要计算每一个warshell 矩阵。
复杂度:
这样,我们声明一个函数,来计算Wn.
void wsMat(bool **arr,int size,int n)//to acquire the nth warshall matrix{ for (int k=0; k<n; k++) { for (int i=0; i<size; i++) { for (int j=0; j<size; j++) {// if (arr[i][j]==1||(arr[i][k]==1&&arr[k][j]==1)) {// arr[i][j]=1;// } arr[i][j]=arr[i][j]+arr[i][k]*arr[k][j]; } } }}注释部分为原来的版本,因为是bool数组,修改为现有版本后变得尤为简洁。
现在来解释为什么前面要用new来声明数组,因为我们本可以使用
bool mat[size][size];
来声明。但是,在这里size作为一个variable,导致mat的类型不是bool **,所以在后面作为函数传入时IDE提示no matching function. 所以只能使用前面的方法。(这里笔者还要研究在深入一些)
iv) 输出结果
这里笔者加了3,6这组关系来测试是否会无视这对关系。
总结:
Warshell's Algorithms 的应用主要在于寻找最短路径。
1 0
- Warshell's Algorithms
- C++ STL's Algorithms
- Euclid's algorithms for GCD
- Algorithms—118.Pascal's Triangle
- Algorithms—119.Pascal's Triangle II
- LeetCode Algorithms #66 <Pascal's Triangle>
- LeetCode Algorithms #119 <Pascal's Triangle II>
- 传递闭包 -》Warshell算法
- Algorithms
- algorithms
- algorithms
- Algorithms
- ALGORITHMS
- Algorithms
- Algorithms
- Comparison of the OpenCV's feature detection algorithms-II
- •dr. dobb's algorithms collection-(2013/11/20)
- Andrew Ng's deeplearning Course2Week2 Optimization algorithms(优化算法)
- 【BZOJ2435】[Noi2011]道路修建【TreeDP】
- Ubuntu上的ftp配置连接
- Mysql导入官方示例employees问题解决记录
- 提供多个地图选择
- ios 延时加载
- Warshell's Algorithms
- CreateFileMapping
- Struts2的模板和主题theme及自定义theme
- PHP程序员最常犯的11个MySQL错误
- C#多线程编程时遇到跨线程访问异常的处理方法
- 关于包含0长数组的结构体对齐问题(C语言 Linux_x64 GNU编译器)
- 关于汇编语言寄存器和指令操作的整理
- LeetCode 219 Contains Duplicate II
- 十进制转m进制(m<=16)