离散数学(1)-偏序的反链分解方法

本文分享了作者在学习离散数学过程中的感悟与实践,包括偏序关系、链和反链等基本概念的理解,以及通过编程实现离散数学中的算法,如反链分解等。

今天是我第一次写博客,还不知道该如何去写,不过第一次写博客还是让我非常激动,前几天看了大四学长学长的博客,看他最开始也是从简单的东西开始写,我就想以后有想法就写下来,总结一下,长久下去,必定会有收获,学长告诉我有时候总结要比计划好的多,可能他写的东西也比较多对这方面深有体会。今年已经大二了,大一一年的时间总想着玩些什么,对大学里一些新鲜的东西很好奇,也并没有好好规划一下自己。大二开学后有了很多想法,试图利用不同的方式规划自己。可能水平有限,还不能达到和别人交流之谈,总之,先开始吧!Come on go go go!

关于离散数学,开始这门课程还不到三个星期,老师说这是这学期最简单的一门课程,并且大部分是和计算机相关。我大致浏览了下课本的目录好像有一种似曾相识的感觉,对了,就是去年的数据结构,他们有好多一样的内容,真的很后悔去年没有好好学习数据结构这门课,哈哈 ,没办法只能告诉自己现在开始还不晚,所以为了弥补数据结构知识的缺失,我打算在离散数学这门课的学习过程中遇到关于编程和算法的地方就动手实践出来,打开Vs2010敲一敲代码,自己冥思苦想也好,借鉴别人的也罢,总之将算法实践一定不会有错。

一.一些基本概念的回顾

1.偏序关系:对于集合S上的关系R 满足下面的三条

1“ R是自反的,即对S中的每个元素x  有  x R x 为真;

2” R是反对称的, 即若 x R y 和 y R x 成立 必有 x=y成立;

3“ R是传递的, 即 x R y   y R z 成立,则有 x R z成立;

2. 链和反链:集合是X的子集, 如果Y中任意两个元素都可以进行比较,就成Y是链,如果Y中任意两个元素都不可比较,称Y为反链。

3. 反链分解的原理: 设X是有限的偏序集, 最长链的大小为R, 则存在 R 个反链构成X 的一个划分。  我们将偏序集分割的方法就是基于这个定理的证明。大致思想是这样的,首先在偏序集中找到所有的极小元,把这些极小元分割出来,剩下的元素仍然是一个偏序结构,再在剩下的元素中找到所有的极小元,这样重复下去,直到开始的集合成为空集。当然 找所有的极大元也是可以的。

4. 关系矩阵:看来我要向一些办法把矩阵搞到博客的页面上来,明天试试那个数学公式编辑器可不可以,简单讲关系矩阵就是代表了元素之间的二元关系,如果对应元素之间有关系,那么矩阵的对应位置就是1,没有关系就为 0. 因为矩阵在计算机上比较容易处理,二维的只需要一个二维数组就可以了,所以下面的实验利用关系矩阵处理偏序集。

二. 实验过程

1. 输入偏序集所对应的关系矩阵。

2.在这个关系矩阵里找到集合的极大元的全体分割出来。

3.重复上边的步骤直到关系矩阵成为0矩阵,也就是完成分割。


// 偏序集反链分解2016_03_16.cpp : 定义控制台应用程序的入口点。
//
#include<stdio.h>
#define N 5
int mat[N][N], degree[N];
void Antichain();
void MatInput(int n);
void main()
{
	int i, j;
	MatInput(N);     //输入偏序集的关系矩阵
	Antichain();
}

void MatInput(int x)
{
	int i, j;
	for(i = 0; i<x; i++)
		for(j = 0; j<x; j++)
			scanf("%d", &mat[i][j]);
	for(i = 0; i<x; i++)
	{
		degree[i] = 0;
		for(j = 0; j<x; j++)
			if(mat[i][j])
				degree[i]++;
	}
			
}

void Antichain()
{
	int i, j, max[N];
	int count = 0, n = 0, sum = N;  //count 统计极大元的数量  n 统计是第几条反链
	while(sum)
	{
		count = 0;
		for(i = 0; i<N; i++)     //统计最大元的数量和最大元对应的角标
			if(degree[i]==1)
				{
					max[count] = i;
					count++;
				}
		printf("第 %d 条反链的元素个数是:%d 元素分别为:", ++n, count);
		for(i = 0; i<count; i++)
		{
			printf("%d  ",max[i]);
		}
		printf("\n");
		for(j = 0; j<count; j++)  //处理下一次的最大元获取
			{
				for(i = 0; i<N; i++)
				{
					if(mat[i][j])
						mat[i][j]=0;
					degree[i]--;
				}
				sum--;
		}
	
	}
	
}

这里处理的是一个5个元素集合对于自身的一个偏序关系。

运行效果如下:


哈哈 感觉很高兴,加油!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值