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

来源:互联网 发布:二阶矩阵卷积运算 编辑:程序博客网 时间:2024/05/07 23:39

      因为该偏序集中任意两个元素的最小公倍数和最大公约数就是这两个元素的最小商界和最大下界因此它是格

cal_factor()函数计算因子,用1n/2(一个正整数n除了它本身的其他因子显然是小于等于n/2)for循环通过判断余数是否为0来找到n的所有因子并存在factor数组中输出

      cal_matrix()函数计算关系矩阵,先将关系矩阵数组matrix初始化为0

通过判断各因子间的整除关系给关系矩阵赋值,若factor[j]%factor[i]==0则说明factor[j]可以整除factor[i],matrix[i][j]值赋为1

      cover()函数计算盖住集,若matrix中的三个元素存在传递关系i-j,j-ki-k显然不是盖住集中的元素,将matrix[i][k]的值赋为0

      gcd()函数计算两个数的最大公约数,辗转相除法

      solve()函数判断是否为有补格,若除了1和这个数n本身的其他因子都能找到一个因子使得与其的最大公约数为1最小公倍数为n,则其为有补格,有一个元素找不到,则不是有补格,直接退出


#include<iostream>#include<cstring>#include<cmath>using namespace std;int n, cnt;   int factor[50];   int matrix[20][20];  void cal_factor()//计算数字的因子                  {cout << "因子为: ";for(int i = 1; i <= n / 2; i++){if(n % i == 0){factor[cnt++] = i;cout << i << ",";}}factor[cnt] = n;cout << factor[cnt] << endl;}void cal_matrix()//计算关系矩阵{memset(matrix, 0, sizeof(matrix));for(int i = 0; i <= cnt; i++)for(int j = 0; j <= cnt; j++)   if(factor[j] % factor[i] == 0)   matrix[i][j] = 1;}void cover()       //盖住集           { cal_matrix();for(int i = 0; i <= cnt; i++){for(int j = 0; j <= cnt; j++){for(int k = 0; k <= cnt; k++)  {matrix[k][k] = 0;if(matrix[i][j] && matrix[j][k])matrix[i][k] = 0;}}}cout << "盖住集为: {";for(i = 0; i <= cnt; i++)for(int j = 0; j <= cnt; j++)if(matrix[i][j])cout << " <" << factor[i] << "," << factor[j] << ">";cout << " }" << endl;}int gcd(int x, int y)//最大公约数   {    int r = 1;    while(r != 0) {r = x % y;x = y;y = r;}    return x;}void solve()           //判断是否为有补格        {bool flag;int Gcd, Lcm;for(int i = 1; i < cnt; i++){flag = false;for(int j = 1; j < cnt; j++){if(i == j)continue;Gcd = gcd(factor[i], factor[j]);            Lcm = factor[i] / Gcd * factor[j];  if(Gcd == factor[0] && Lcm == factor[cnt]){flag = true;break;}if(!flag){cout << "该格不是有补格!" << endl;return;}}}cout << "该格是有补格!" << endl;return;}int main(){cnt = 0;cout << "请输入一个正整数: ";cin >> n;cal_factor();cover();solve();return 0;}


2 0