⑴ 用c语言求一个关系矩阵的传递闭包
首先,矩阵的并运算不是很对,执行结果好象是第二条赋值语句,没有实现并的概念;
然后,设计到返回数组首地址的函数中,尝试一下把所有需要返回的数组定义为全局变量或者主函数中的参数变量,因为子函数执行完毕后,所申请的内存会被释放,地址便无效;
再次,函数调用,传递数组的首地址才对,而不是数组某一个元素;
最后,子函数定义中,参数变量是二维数组,要写上数组的维数,例如void tran(int a[6][6],int b[6][6]),不然会因为维数不确定而报错.
⑵ 用c语言编写传递闭包时 A[j][k]=A[j][k]||A[i][k];为什么这么写
C语言不支持内嵌函数,没有闭包。
⑶ 求计算机求解关系R的传递闭包 C语言算法
传递闭包,最简单的技术是采用 【弗洛伊德算法】
Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。
Floyd-Warshall算法的时间复杂度为O(N3),空间复杂度为O(N2)。
Floyd-Warshall算法的原理是动态规划。
设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。
1.若最短路径经过点k,则Di,j,k = Di,k,k − 1 + Dk,j,k − 1;
2.若最短路径不经过点k,则Di,j,k = Di,j,k − 1。
因此,Di,j,k = min(Di,k,k − 1 + Dk,j,k − 1,Di,j,k − 1)。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。
代码请见:
⑷ 离散数学中传递闭包怎么求 通俗一点
方法:warshall法,即运行n次,每次使得MR[n][i],MR[i][n]都为1时使得MR[i][j]为1,否则还是为MR[i][j]。
传递闭包的计算过程一般可以用Warshell算法描述:
For 每个节点i Do
For 每个节点j Do
If j能到i Then
For 每个节点k Do
a[j, k] := a[j, k] Or ( a[j, i] And a[ i, k] )
其中a数组为布尔数组,用来描述两个节点是否相连,可以看做一个无权图的邻接矩阵。算法过程跟Floyd很相似,三重循环,枚举每个中间节点。不过传递闭包只需要求出两个节点是否相连,而不用求其间的最短路径长。
传递性:对于一个节点i,如果j能到i,i能到k,那么j就能到k。求传递闭包,就是把图中所有满足这样传递性的节点都弄出来,计算完成后,就知道任意两个节点之间是否相连。
传递闭包的定义:R’是R(不具有传递性质)变动最少的步骤得到的具有传递性质的关系。
(4)用c语言求传递闭包扩展阅读
算法实例:
#include<stdio.h>
#define
N
10
int
judge(int
k,int
i,int
j)
{
if(i==1
&&
j==1){
return
1;
}
return
k;
}
void
warShall(int
MR[N][N],int
n)
{
for(int
k=0;k<n;k++){
for(int
i=0;i<n;i++){
for(int
j=0;j<n;j++){
if(i!=k
||
j!=k){
MR[i][j]=judge(MR[i][j],MR[k][j],MR[i][k]);
}
}
}
}
}
int
main()
{
int
MR[10][10];
int
mul;
scanf("%d",&mul);
for(int
i=0;i<mul;i++){
for(int
j=0;j<mul;j++){
scanf("%d",&MR[i][j]);
}
}
printf("求传递闭包为:\n");
warShall(MR,mul);
for(int
i=0;i<mul;i++){
for(int
j=0;j<mul;j++){
printf("%d
",MR[i][j]);
}
printf("\n");
}
return
0;
}
运行结果:
参考资料:网络-传递闭包
⑸ 用c语言编 一个关系的传递闭包
说明:以关系矩阵形式计算传递闭包: #include"stdio.h" #define N 1000 main() { int i,j,a[N][N],b[N][N],c[N][N],s=0,k,e[N][N],m,n; printf("请输入你的关系矩阵的阶n(n<=1000):\n"); scanf("%d",&n); printf("请输入你的关系矩阵:\n"); for(i=0;i<n;i++) for(j=0;j<n;j++) { scanf("%d",&a[i][j]); e[i][j]=a[i][j]; b[i][j]=a[i][j]; } for(m=1;m<n;m++) { for(i=0;i<n;i++) for(j=0;j<n;j++) { for(s=0,k=0;k<n;k++) s+=b[i][k]*a[k][j]; c[i][j]=s; if(e[i][j]==0&&c[i][j]!=0) e[i][j]=c[i][j]; } for(i=0;i<n;i++) for(j=0;j<n;j++) b[i][j]=c[i][j]; } for(i=0;i<n;i++) for(j=0;j<n;j++) if(e[i][j]!=0) printf("<%d,%d>,",i+1,j+1); printf("\n"); }
⑹ 离散数学中传递闭包怎么求 通俗一点
方法:warshall法,即运行n次,每次使得MR[n][i],MR[i][n]都为1时使得MR[i][j]为1,否则还是为MR[i][j]。
传递闭包的计算过程一般可以用Warshell算法描述:
For 每个节点i Do
For 每个节点j Do
If j能到i Then
For 每个节点k Do
a[j, k] := a[j, k] Or ( a[j, i] And a[ i, k] )
其中a数组为布尔数组,用来描述两个节点是否相连,可以看做一个无权图的邻接矩阵。算法过程跟Floyd很相似,三重循环,枚举每个中间节点。不过传递闭包只需要求出两个节点是否相连,而不用求其间的最短路径长。
传递性:对于一个节点i,如果j能到i,i能到k,那么j就能到k。求传递闭包,就是把图中所有满足这样传递性的节点都弄出来,计算完成后,就知道任意两个节点之间是否相连。
传递闭包的定义:R’是R(不具有传递性质)变动最少的步骤得到的具有传递性质的关系。
(6)用c语言求传递闭包扩展阅读
算法实例:
#include
#define
N
10
int
judge(int
k,int
i,int
j)
{
if(i==1
&&
j==1){
return
1;
}
return
k;
}
void
warShall(int
MR[N][N],int
n)
{
for(int
k=0;k<n;k++){
for(int
i=0;i<n;i++){
for(int
j=0;j<n;j++){
if(i!=k
||
j!=k){
MR[i][j]=judge(MR[i][j],MR[k][j],MR[i][k]);
}
}
}
}
}
int
main()
{
int
MR[10][10];
int
mul;
scanf("%d",&mul);
for(int
i=0;i<mul;i++){
for(int
j=0;j<mul;j++){
scanf("%d",&MR[i][j]);
}
}
printf("求传递闭包为:\n");
warShall(MR,mul);
for(int
i=0;i<mul;i++){
for(int
j=0;j<mul;j++){
printf("%d
",MR[i][j]);
}
printf("\n");
}
return
0;
}
运行结果:
参考资料:网络-传递闭包
⑺ (离散数学)输入一个关系矩阵,用C语言编程求出它的自反闭包,对称闭包和传递闭包
我用面向对象写的 自己改一下
#include<iostream.h>
template<class T>
void Warshall( T *a , int m , int n )
{
int i = 0,j = 0;
for( i = 0 ; i < n ; i++ )
{
for( j = 0 ; j < m ; j++ )
{
if( a[j][i] == 1 )
{
int k = 0;
for( int x = 0 ; x < n ; x++ )
{
a[j][k] = a[j][k] || a[i][k];
k++;
}
}
}
}
for( i = 0 ; i < m ; i++ )
{
for( j = 0 ; j < n ; j++ )
{
cout << a[i][j] << '\t';
}
cout<<endl;
}
}
void main()
{
int ai[4][4] = { {0,1,0,0} , {1,0,1,0} , {0,0,0,1} , {0,0,0,0} };
Warshall(ai,4,4);
}
⑻ 1.利用求传递闭包的Warshall算法,给定关系R,编写求R的可传递闭包的C语言程序并利用下列数据测试。
c++版
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
int n_dim=0;
cout<<"Input number of dimensions:";
cin>>n_dim;
char **array=new char*[n_dim]; //以下是动态创建一个 n_dim*n_dim 数组,如不太清楚的看我BLOG里的
char ch; //另一篇关于动态数组的文章
for(int i=0;i<n_dim;i++)
{
array[i]=new char[n_dim]; //这句也是
for(int j=0;j<n_dim;j++)
{
cin>>ch;
array[i][j]=ch;
}
}
for(i=0;i<n_dim;i++)
for(int j=0;j<n_dim;j++)
for(int k=0;k<n_dim;k++)
if(array[i][j]=='1'&&array[k][i]=='1')
array[k][j]='1';
cout<<"The trasitive closure of a relation R represented:"<<endl;
for(i=0;i<n_dim;i++)
{
for(int j=0;j<n_dim;j++)
cout<<array[i][j];
cout<<endl;
}
}
另一c++
#include <iostream>
#include <string>
using namespace std;
int **matrix;
void warshall(int n,int **m);
void setValue(int elem1,int elem2,int value);
void buildMatrix(int numElement);
int main()
{
int num;
string str;
cout << "Please input the number of elements:" << endl;
cin >> num;
buildMatrix(num);
cout << "Please input a set,such as R={(x1,x2),(x3,x4),...}: " << endl;
cin >> str;
for(int i=0;i<str.size();i++)
if((str.at(i)=='(') && (str.at(i+2)==','))
setValue(str.at(i+1)-'0',str.at(i+3)-'0',1);
warshall(num,matrix);
return 0;
}
void warshall(int n,int **m)
{
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(m[j][i] == 1)
for(k=0;k<n;k++)
m[j][k] = m[j][k] || m[i][k];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout << " " << m[i][j] << " ";
cout << endl;
}
}
void setValue(int elem1,int elem2,int value)
{
if(value>0)
matrix[elem1-1][elem2-1] = value;
}
void buildMatrix(int numElement)
{
int i,j;
matrix = (int**) new int*[numElement];
for(i=0;i<numElement;i++)
matrix[i] = new int[numElement];
for(j=0;j<numElement;j++)
for(i=0;i<numElement;i++)
matrix[j][i] = 0;
}
⑼ 离散数学Warshall算法求传递闭包C语言实现
#include <stdio.h>#include <stdlib.h>#define N 20#define M 20main(){ int i,j,k,m,n; int r1[M],r2[M],a[N],mr[N][N]={0}; FILE * fp; printf("程序自动调用c:/stone2.txt文件内相应数据\n"); fp=fopen("c:\\stone2.txt","r"); fscanf(fp,"%d",&n); /*读取集合元素个数*/ for(i=0;i<n;i++) /*读取集合元素*/ fscanf(fp,"%d",&a[i]); fscanf(fp,"%d",&m); /*读取关系个数*/ for(k=0;k<m;k++) fscanf(fp,"%d,%d",&r1[k],&r2[k]); /*读取关系*/ fclose(fp); printf("自反闭包r(R):\n{"); for(i=0;i<n;i++) printf("<%d,%d>,",a[i],a[i]); /*输出自反闭包*/ for(k=0;k<m;k++) { if(r1[k]!=r2[k]) printf("<%d,%d>,",r1[k],r2[k]); else continue; } printf("\b}\n"); printf("对称闭包s(R):\n{"); /*输出对称闭包*/ for(k=0;k<m;k++) { if(r1[k]!=r2[k]) printf("<%d,%d>,<%d,%d>,",r1[k],r2[k],r2[k],r1[k]); else printf("<%d,%d>,",r1[k],r2[k]); } printf("\b}\n"); k=0; for(i=0;i<n,k<m;i++) { if(r1[k]!=a[i]) continue; else { for(j=0;j<n,k<m;j++) /*关系转换成矩阵*/ { if(r2[k]!=a[j]) continue; else { mr[i][j]=1; k++; i=0;j=0; break; } } } } printf("关系所对应的关系矩阵:\n"); for(i=0;i<n;i++) { /*打印关系矩阵*/ for(j=0;j<n;j++) printf("%5d",mr[i][j]); printf("\n"); } for(k=0;k<n;k++) for(i=0;i<n;i++) /*warshall*/ for(j=0;j<n;j++) mr[i][j]+=mr[i][j]+mr[i][k]*mr[k][j]; for(i=0;i<n;i++) for(j=0;j<n;j++) { /*把mr[]非0项赋值为1*/ if(!mr[i][j]) continue; else mr[i][j]=1; } printf("传递闭包对应关系矩阵:\n"); for(i=0;i<n;i++) { /*输出传递闭包对应的关系矩阵*/ for(j=0;j<n;j++) printf("%5d",mr[i][j]); printf("\n"); } system("PAUSE");}自己写的,三个闭包都有,包括传递闭包,看注释就知道了,还是用文件读写,方便数据输入
⑽ 编程:求一个关系的传递闭包(C语言)
利用关系的矩阵表示,可以通过Warshall算法计算有限集合上的二元关系的传递闭包。