離散實驗——二元關係及其性質

【實驗目的】編程

掌握二元關係在計算機上的表示方法,並掌握若是斷定關係的性質。ide

【實驗內容】測試

編程判斷一個二元關係是否爲等價關係,若是是,求其商集。flex

例:A={1,2,3,4,5,6,7,8,9,10},R={<x,y>|x、y∈A∧y≡x (mod 5)}判斷R是否等價關係,若是是,求出各等價類。spa

A 上知足 關係的有 : code

<1,1>,<2,2>,<3,3>,<4,4>,<5,5>,<6,6>,<7,7>,<8,8>,<9,9>,<10,10>,blog

<1,6>,<2,7>,<3,8>,<4,9>,<5,10>,it

<6,1>,<7,2>,<8,3>,<9,4>,<10,5>io

 

【源程序及解析】class

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define N 10086
int a[N][N], n;
void init()
{
    printf("請輸入二元關係的域的個數:");
    scanf("%d", &n);
    printf("請輸入關係矩陣。\n");
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            scanf("%d", &a[i][j]);
        }
    }
}
int judge_R(int flag)   // 判斷是否是 自反關係
{
    for (int i = 0; i < n&&flag; i++)
        if (a[i][i] == 0)
            flag = 0;
    if (flag)
        return 1;
    return 0;
}
int judge_S(int flag)   // 判斷是否是 對稱關係
{
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (a[i][j] && !a[j][i])
                flag = 0;
    if (flag)
        return 1;
    return 0;
}
int judge_T(int flag)   // 判斷是否是 傳遞關係
{
    for (int i = 0; i < n&&flag; i++)
        for (int j = 0; j < n&&flag; j++)
            for (int k = 0; k < n&&flag; k++)
                if (a[i][j] && a[j][k] && !a[i][k])
                    flag = 0;
    if (flag)
        return 1;
    return 0;
}
void show()
{
    int fld[N];  // 二元關係的 域
    for (int i = 0; i < n; i++)
        fld[i] = i + 1;   // i 表明第 i 個元素

    printf("\n商集爲:\n");
    printf("{ ");
    for (int i = 0; i < n; i++)   //循環全部元素
    {
        if (fld[i])   // 若是當前元素 所屬的等價類 還沒打印出來
        {
            printf("{ ");
            for (int j = 0; j < n; j++)
            {
                if (a[i][j] && fld[j])  //  若是與當前元素連通的元素 所屬的等價類 還沒打印出來
                {
                    printf("%d ", fld[j]);
                    fld[j] = 0;   // 標記 用過的元素,至於 i,由於不會重複循環,因此不用 標記
                }
            }
            printf("} ");
        }
    }
    printf("}\n");
}
int main(void)
{
    init();   // 初始化矩陣
   
    if (judge_R(1)&&judge_S(1)&&judge_T(1))  // 判斷是不是等價關係
        // if (judge_R&&judge_S&&judge_T)  怎麼這句沒報錯
        show();    // 打印商集
    else
        printf("該二元關係不是等價關係。\n");

    system("pause");
    return 0;
}
/*測試數據:
10
1 0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0 0 0 
0 1 0 0 0 0 1 0 0 0 
0 0 1 0 0 0 0 1 0 0
0 0 0 1 0 0 0 0 1 0 
0 0 0 0 1 0 0 0 0 1 

結果爲:
商集爲:
{ { 1 6 } { 2 7 } { 3 8 } { 4 9 } { 5 10 } }
*/
View Code

 

 

 一,等價關係的判斷

 

1,自反性 (Reflexve) 的判斷 

若 關係矩陣 主對角線上的元素都是 1,則 R 具備自反性

int judge_R(int flag)   // 判斷是否是 自反關係
{
	for (int i = 0; i < n&&flag; i++)
		if (a[i][i] == 0)
			flag = 0;
	if (flag)
		return 1;
	return 0;
}

 

2,對稱關係 ( Symmetric)  的判斷

若 關係矩陣 a [ i] [ j ] == a [ j ] [ i ],則 R 具備對稱性

int judge_S(int flag)   // 判斷是否是 對稱關係
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (a[i][j] && !a[j][i])
				flag = 0;
	if (flag)
		return 1;
	return 0;
}

  

3,傳遞性(Transitive)的判斷

若 關係矩陣 對任意的存在 i 經過 j 到達  k  的路徑,都有 i 直接到達  k 的路徑,則 R 具備 傳遞性

即 若是 a[i][j] ==1, a[j][k] ==1,則 a[i][k] ==1

int judge_T(int flag)   // 判斷是否是 傳遞關係
{
	for (int i = 0; i < n&&flag; i++)
		for (int j = 0; j < n&&flag; j++)
			for (int k = 0; k < n&&flag; k++)
				if (a[i][j] && a[j][k] && !a[i][k])
					flag = 0;
	if (flag)
		return 1;
	return 0;
}

  

 二,商集的求法

void show()
{
	int fld[N];  // 二元關係的 域
	for (int i = 0; i < n; i++)
		fld[i] = i + 1;   // i 表明第 i 個元素

	printf("\n商集爲:\n");
	printf("{ ");
	for (int i = 0; i < n; i++)   //循環全部元素
	{
		if (fld[i])   // 若是當前元素 所屬的等價類 還沒打印出來
		{
			printf("{ ");
			for (int j = 0; j < n; j++)
			{
				if (a[i][j] && fld[j])  //  若是與當前元素連通的元素 所屬的等價類 還沒打印出來
				{
					printf("%d ", fld[j]);
					fld[j] = 0;   // 標記 用過的元素,至於 i,由於不會重複循環,因此不用 標記
				}
			}
			printf("} ");
		}
	}
	printf("}\n");
}

商集是由等價類組成的集合,由於全部的等價類都是沒有 交集 的,且若 xRy ,則 [x] = [y]

因此咱們先循環 二元關係的域,找出與全部與當前元素 連通的 元素,他們就組成了 一個等價類

再把 用過的元素標記一下,就能夠不用 小心重複了。

 

 

 

  

============ ========== ========= ======= ======= ===== ==== === == =

我好像是一個在海邊玩耍的孩子,不時爲拾到比一般更光滑的石子或更美麗的貝殼而歡欣鼓舞,

而展示在我面前的是徹底未探明的真理之海。

                          —— —— 艾薩克·牛頓

相關文章
相關標籤/搜索