离散数学判定关系

在这里的代码,用于判断是否是自反,是否是对称,是否是传递。

首先,为了避免无效copy,先把自反、对称、传递的概念重复一遍吧。

1、自反性:若M(R的关系矩阵)的主对角线元素均为1,则R是自反关系;若M(R的关系矩阵)的主对角线元素均为0,则R是反自反关系;若M(R的关系矩阵)的主对角线元素既有1又有0,则R既不是自反关系也不是反自反关系。本算法可以作为判等价关系算法的子程序给出。

2、对称性:若M(R的关系矩阵)为对称矩阵,则R是对称关系;若M为反对称矩阵,则R是反对称关系。因为R为对称的是等价关系的必要条件,所以,本算法可以作为判等价关系算法的子程序给出。

3、传递性:若M(R的关系矩阵)为传递矩阵,则R是传递关系;若M为非传递矩阵,则R是非传递关系。

关系矩阵:能清楚地表明此二集合的任意元素是否有此关系的数字矩阵。

代码如下:

#include

#include

#include

#include

#include

#define M  100

char *get_element(char *p)//输入结点序列函数

{

    printf("输入集合的元素(不能有空格):");

    gets(p);

    fflush(stdin);

    return p;

}

int get_position(char ch,char *point){

    int i;

    for(i=0;*(point+i);i++)

        if(*(point+i)==ch)

            return i;

        return 0;

}

void get_relation(int (*a)[M],char *p)

{

    int k1,k2;

    char ch1,ch2;

    printf("输入关系的各个序偶(以<*,*>时结束):\n");

    while(1)

    {

        printf("<");

        ch1=getche();

        printf(",");

        ch2=getche();

        printf(">\n");

        if(ch1=='*')break;

        k1=get_position(ch1,p);

        k2=get_position(ch2,p);

        a[k1][k2]=1;

    }

}

void output_relat_array(int (*a)[M],int arry_w)//输出关系矩阵

{

    int i,j;

    for(i=0;i

    {

        for(j=0;j

            printf("%4d",a[i][j]);

        printf("\n");

    }

}

void output_relate(int (*a)[M],int arry_w,char *p)

//关系矩阵中如果有元素为1,则根据该序号去结点序列中查找其相应结点

{

    int i,j;

    int count=0;

    

    printf("{");

    for(i=0;i

        for(j=0;j

           if(a[i][j]==1){ printf("<%c,%c>,",*(p+i),*(p+j));count++;}

    printf("\b}");

    printf("\n");

}

int ZF(int (*a)[M],int n)

{

    int flag1 = 1;  

    for(int i = 0; i

     //只要有一个对角元素为0就不具有自反性  

    {

        if(!a[i][i])  

        {    

            flag1 = 0;  

            break;

        }

    }

    return flag1;

}

int FZF(int (*a)[M],int n) //反自反  

{  

    int flag2 = 1;  

    for(int i = 0; i < n; i++)  

    {  

        //只要有一个对角元素为1就不具有反自反性  

        if(a[i][i])  

        {  

            flag2 = 0;  

                   break;

        }  

    }  

    return flag2;

}  

  

int  DC(int (*a)[M],int n)  //对称  

{  

    int flag3 = 1;  

    for(int i = 0; i < n; i++)  

        for(int j = 0; j < n; j++)  

        { //矩阵中对称元素都相等则具有对称性  

            if(a[i][j] != a[j][i])  

                 flag3 = 0;  

                break;

        }  

            return flag3;

}  

int FDC(int (*a)[M],int n) //反对称  

{  

    int flag4 = 1;  

    for(int i = 0; i < n; i++)  

        for(int j = 0; j < n; j++)  

            //矩阵中对称元素中有相等的1则不具有反对称性  

            if(a[i][j] && a[i][j] == a[j][i] && i != j)  

            {  

                flag4 = 0;  

                break;

            }  

            return flag4;

}    

int CD(int (*a)[M],int n) //传递  

{  

   int flag5 = 1;  

    for(int i = 0; i < n; i++)  

        for(int j = 0; j < n; j++)  

            for(int k = 0; k < n; k++)  

                //判断是否满足传递关系  

                if(a[i][j] && a[j][k] && !a[i][k])  

                {  

                    flag5 = 0;  

                    break;

                }  

                return flag5;

}  

 int main()

{

     int a[M][M]={0};

    char point[M];

    int stlen;

    char *p;

    p=get_element(point);//输入结点p取得其起始位置

    stlen=strlen(point);

    get_relation(a,p);//根据输入的关系的序偶构建关系矩阵a

    output_relate(a,stlen,p);

    printf("\n关系矩阵为:\n");

    output_relat_array(a,stlen);

    cout<<"该关系具有的性质:"<

    if(ZF(a,stlen))

       {

           cout<<"自反性"<

       }

    if(FZF(a,stlen))

        {

            cout<<"反自反性"<

        }

    if(DC(a,stlen))

    {

        cout<<"对称性"<

    }

    if(FDC(a,stlen))

    {

        cout<<"反对称性"<

    }

    if(CD(a,stlen))

    {

        cout<<"传递性"<

    }

    return 0;

}

总结一下自反反自反对称反对称传递的特点

1.自反,就是如果集合A中的每个元素x,都有xRx,也就是说,这些关系里,a = b的个数应该是A.size()个。

2.反自反,就是集合中的每个元素都没有xRx,也就是说,再没有一个是a,b相同的。

3.对称,就是如果有关系,一定有关系(a ≠ b)

4.反对称,就是如果有关系,就一定没有关系(a ≠ b)

5.传递,就是如果有关系, ,那么一定有

到这就没有了,(作业只完成了一半,明天继续)

你可能感兴趣的:(自主学习,算法)