南邮离散数学实验三-偏序关系中盖住关系的求取及格论中有补格的判定

一、    实验目的和要求

内容:

编程实现整除关系这一偏序关系上所有盖住关系的求取,并判定对应偏序集是否为格。

要求:

对任意给定正整数,利用整除关系求所有由其因子构成的集合所构成的格,判断其是否为格、有界格、有补格。并输出所有元素各自的补元素。



程序要求输入任意整数,输出它所有的因子,所有的整除关系,所有的盖住关系,判断对应的偏序集是不是一个格,是不是一个有界格,如果是有界格,是不是一个有补格,如果是有补格,输出所有元素的补元素,如果不是有补格,输出没有补元素的元素,以及有补元素的元素的补元素。

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int n;  //保存输入的整数n
vector<int> a; //保存n的所以因子

struct note //表示序偶的结构体
{
    int x,y;
    note(int aa,int bb)
    {
        x=aa;
        y=bb;
    }
};

vector<note> zhenchu; //保存所有整除关系的序偶
vector<note> COV; //保存所有盖住关系的序偶
vector<int> HasNoBu; //保存没有补元素的元素
vector<int> Bu[10000]; //保存有补元素的元素的补元素

void Prime()  //计算出n的因子
{
    for(int i=1;i<=n;i++)
    {
        if(n%i==0)
        {
            a.push_back(i);
        }
    }
}

void Divided() //计算出整除关系 并保存在zhenchu数组
{
    for(int i=0;i<a.size();i++)
    {
        for(int j=i;j<a.size();j++)
        {
            if(a[j]%a[i]==0)
            {
                note tmp(a[i],a[j]);
                zhenchu.push_back(tmp);
            }
        }
    }
}

void SolveCOV()  //计算出所有盖住关系,并保存在COV数组
{
    for(int i=0;i<a.size()-1;i++)
    {
        for(int j=i+1;j<a.size();j++)
        {
            if(a[j]%a[i]==0)
            {
                int flag=0;
                for(int k=i+1;k<j;k++)
                {
                    if(a[k]%a[i]==0&&a[j]%a[k]==0)
                    {
                        flag=1;
                        break;
                    }
                }
                if(flag==0)
                {
                    note tmp(a[i],a[j]);
                    COV.push_back(tmp);
                }
            }
        }
    }
}

int gcd(int x,int y)  //计算最小公倍数
{
    int r=1;
    while(r)
    {
        r=y%x;
        y=x;
        x=r;
    }
    return y;
}




bool JudgeGe()  //判断是不是格
{
    for(int i=0;i<a.size();i++)
    {
        for(int j=i+1;j<a.size();j++)
        {
            int index=find(a.begin(),a.end(),gcd(a[i],a[j]))-a.begin();
            if(index==a.size())
            {
                return false;
            }
            index=find(a.begin(),a.end(),a[i]*a[j]/gcd(a[i],a[j]))-a.begin();
            if(index==a.size())
            {
                return false;
            }
        }
    }
    return true;
}


int G[10010][10010]; //判断是不是有界格用到的图
int flag; //深度优先搜索过程中,如果找到某个元素不比最大元素小,则flag标志成1
void DFS(int cur)
{
    if(flag) return;
    int tmp=0;
    for(int i=cur+1;i<=n;i++)
    {
        if(G[cur][i]==1)
        {
            tmp=1;
            break;
        }
    }
    if(tmp==0&&cur!=n)  //找到不是有界格的条件
    {
        flag=1;
        return ;
    }
    for(int i=cur+1;i<=n;i++)
    {
        if(G[cur][i]==1)
        {
            DFS(i);
        }
    }
}




bool JudgeYouJieGe()  //判断有界格,用有向图的深度优先遍历来判断是不是有界格
{
    flag=0;
    memset(G,0,sizeof(G));
    for(int i=0;i<COV.size();i++)
    {
        G[COV[i].x][COV[i].y]=1;
    }
    DFS(1);
    if(flag==0)
    {
        return true;
    }
    else
    {
        return false;
    }
}


bool JudgeYouBuGe()  //判断是不是有补格
{
    int judge=0;
    for(int i=0;i<a.size();i++)
    {
        int tmp=0;
        for(int j=0;j<a.size();j++)
        {
            if(gcd(a[i],a[j])==1 && a[i]*a[j]/gcd(a[i],a[j])==n)
            {
                tmp=1;
                Bu[i].push_back(a[j]);
            }
        }
        if(tmp==0)
        {
            judge=1;
            HasNoBu.push_back(a[i]);
        }
    }
    if(judge==1)
    {
        return false;
    }
    else
    {
        return true;
    }
}





int main()
{
    printf("请输入整数n:");
    scanf("%d",&n);
    Prime();
    printf("\n%d的所有因子为:\n",n);
    for(int i=0;i<a.size();i++)
    {
        printf("%d ",a[i]);
    }
    Divided();
    printf("\n\n所有的整除关系为:\n{");
    for(int i=0;i<zhenchu.size();i++)
    {
        if(i==0) printf("<%d,%d>",zhenchu[i].x,zhenchu[i].y);
        else printf(",<%d,%d>",zhenchu[i].x,zhenchu[i].y);
    }
    printf("}\n\n");
    SolveCOV();
    printf("所有的盖住关系为:\nCOV A={");
    for(int i=0;i<COV.size();i++)
    {
        if(i==0) printf("<%d,%d>",COV[i].x,COV[i].y);
        else printf(",<%d,%d>",COV[i].x,COV[i].y);
    }
    printf("}\n\n");
    if(JudgeGe()==true)
    {
        printf("经过判断,这个偏序集是一个格\n\n");
    }
    else
    {
        printf("经过判断,这个偏序集不是一个格\n\n");
    }
    bool youjiege=JudgeYouJieGe();
    if(youjiege==true)
    {
        printf("经过判断,这个偏序集是一个有界格\n\n");
    }
    else
    {
        printf("经过判断,这个偏序集不是一个有界格\n\n");
    }
    if(youjiege==true)
    {
        if(JudgeYouBuGe()==true)
        {
            printf("经过判断,这个偏序集是一个有补格\n各个元素的补元素分别是:\n");
            for(int i=0;i<a.size();i++)
            {
                printf("%d 的补元素是:",a[i]);
                for(int j=0;j<Bu[i].size();j++)
                {
                    printf("%d ",Bu[i][j]);
                }
                printf("\n");
            }
        }
        else
        {
            printf("经过判断,这个偏序集不是一个有补格\n\n没有补元素的元素是:");
            for(int i=0;i<HasNoBu.size();i++)
            {
                printf("%d ",HasNoBu[i]);
            }
            printf("\n\n");
            printf("其余元素都有补元素,各自的补元素分别是:\n");
            for(int i=0;i<a.size();i++)
            {
                if(Bu[i].size()!=0)
                {
                    printf("%d 的补元素是:",a[i]);
                    for(int j=0;j<Bu[i].size();j++)
                    {
                        printf("%d ",Bu[i][j]);
                    }
                    printf("\n");
                }
            }
        }
    }

    return 0;
}


  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值