matlab实现关系证明

在课程的安排下接触了MATLAB这个软件,其具有一定的优势
我就跟着大佬的博客学了点皮毛,现在来试试手

证明既定关系

给出如下所示的学生成绩统计表

学生\课程A₁A₂……An
X₁A₁(X₁)A₂(X₁)…………
X₂A₁(X₁)A₂(X₁)…………
…………………………
Xm………………An(Xm

根据学生的学习成绩,写出求解获取所有学生的集合上序关系的算法描述:即 若学生Xi,在所有课程上的成绩都优于学生Xj,则学生对(Xi,Xj)满足序关系,这一序关系以矩阵的形式输出。

思路

有n个学生,就构建一个n行n列的学生矩阵,比对每个学生与其他学生的关系
满足“序关系”(成绩全方面超过别人)就置为1,否则置为0

伪代码形式如下:

Input 学生成绩统计表
获取成绩表中学生人数m,课程数目n
初始化学生矩阵student_matrix(m,m)为零矩阵

for i=1:m 
    for j=1:m 
        if 第i个学生所有成绩 > 第j个学生所有成绩
            student_matrix(i,j)=1; 
        end	if
    end	for
end	for
Output student_matrix

MATLAB代码

clc
clear all

table=rand(7,3).*100 %这里是为了方便测试生成的成绩表,实际应该题目给出

[m,n]=size(table) %m为学生数目,n为课程数目
student_matrix=zeros(m,m);

for i=1:m %从第一个学生一直到最后一个
    for j=1:m %当前第i个学生和一共m个学生依次比对
        if(table(i,:)>table(j,:)) %如果所有课程成绩都大于另一个同学
            student_matrix(i,j)=1; %学生矩阵对应部分置为1,以示满足序关系
        end
    end
end
 output=student_matrix %输出学生矩阵

用7位学生,随机生成的3门数据结果如下
在这里插入图片描述
序关系矩阵如下
在这里插入图片描述

证明等价关系

给定一个m×m的矩阵M,用以表示定义在集合A上的一个二元关系,设计算法用以判断这一矩阵所表示的二元关系是否满足等价关系

思路

等价关系分三步:自反、对称、传递
自反性用一次for循环,遍历关系矩阵M对角线上元素即可
对称性用两次for循环,遍历M中(i,j)为1的部分,判断(j,i)是否为1
传递性用三层for循环,遍历M中(i,j)为1且(j,k)为1的部分,M(i,k)是否为1

伪代码形式如下:

Input 关系矩阵M,矩阵规模m

定义函数 reflective: 参数M,m
	for i=1:m
		if M(i,i)!=1
			return false
		end if
	end for
	return true
end

定义函数 symmetric: 参数M,m
	for i=1:m
		for j=1:m
			if M(i,j)==1 and M(j,i)!=1
				return false
			end if
		end for
	end for
	return true
end

定义函数 transitive: 参数M,m
	for i=1:m
		for j=1:m
			for k=1:m
				if M(i,j)==1 and M(j,k)==1 and M(i,k)!=1
					return false
				end if
			end for
		end for
	end for
	return true
end

主函数:
if reflective(M,m)and symmetric(M,m)and transitive(M,m)
	output 这是一个等价关系
else
	output 这不是一个等价关系
end if

MATLAB代码

matlab函数需要新建文件(同目录下)重新编写

function [r] = reflective(M,m)
	for i=1:m
		if M(i,i)~=1
			r=0;
            break;
		end 
	end 
	r=1
end

function [t]=transitive(M,m)
	for i=1:m
		for j=1:m
			for k=1:m
				if M(i,j)==1 && M(j,k)==1 && M(i,k)~=1
					t = 0;
                    break
				end 
			end 
		end 
	end 
	t = 1;
end

M=[1,1,0,1;
    1,1,0,0;
    0,0,1,0;
    1,0,0,1];
[~,m]=size(M)
if reflective(M,m)==1 && symmetric(M,m)==1 && transitive(M,m)==1
    output='这是等价关系'
end  

证明关系的划分

给定一个m×m的矩阵M用以表示一个等价关系,该等价关系是定义在集合A上的,即|A|=m,设计算法求得这个等价关系所对应的划分。

思路

首先了解等价关系对应的划分
在这里插入图片描述

通俗来讲
等价关系→划分:彼此满足关系的元素构成一个集合(block),所有的block组成对应的划分
比如关系对(1,1)(1,2)(2,1)(2,2)构成集合{1,2},关系对(3,3)构成集合{3}那么整个关系(1,1)(1,2)(2,1)(2,2)(3,3)对应的划分就是{{1,2},{3}}
划分→等价关系:划分中的每个block自己与自己形成笛卡尔积,其元素就形成关系对,所有关系对合起来就是对应的等价关系,例子我就不举了,传送门里面说的很详细

回到题目,要求关系对应的划分,根据关系矩阵找出每个关系对形成的block,所有block合并就是对应的划分

伪代码如下:

Input 等价关系矩阵M,矩阵长度m,集合A
创建容器partition 和 block
for i=1:m
	for j=1:m
		if M(i,j)==1
			block中加入A(j)
		end if
	end for
	for b in partition
		if block 与b有交集
			block与b取并集存储在b中
		end if
	end for
	if block与partition每个元素都没交集
		partition加入block
	end if
	block清空,准备下一轮存储
end for
Output partition

特别鸣谢

某位不愿透露姓名的DNA与我共同商议matlab方法,才有以下代码

java代码

public static void main(String[] args) {
        int[] A={1,2,3,4};
        int[][] M={
                {1,1,0,1},
                {1,1,0,0},
                {0,0,1,0},
                {1,0,0,1}
        };
        Set<Integer> block=new HashSet<Integer>() {};
        Set<Set> partition=new HashSet<Set>() {};
        for(int i=0;i<M.length;i++){
            for(int j=0;j<M[0].length;j++){
                if(M[i][j]==1){
                    block.add(A[j]);
                }
            }
            if(!partition.isEmpty()){//非空再判断是否有交集,是空集的话直接加入
                int flag=0;
                for(Set s:partition){
                    Set<Integer> t=new HashSet<Integer>(s);//确保对原来的s无改动
                    t.retainAll(block);//取交集
                    if(t.size()!=0){//若有交集(交集大小不是0),则合并
                        flag=1;
                        s.addAll(block);
                        break;
                    }
                }//若与现存的每个block都无交集,则flag保持为0.直接添加该block
                if(flag==0){
                    partition.add(block);
                }
            }else{
                partition.add(block);
            }
            block=new HashSet<Integer>();//换个新空间,否则会改动partition内的值
        }
        System.out.println(partition);
    }

MATLAB代码

MATLAB没有严格的集合,只能先用数组表示,其核心思想是标识各个元素的录入状况

clc
clear all

A=[1,2,3,4] 
M=[1,1,0,1;
    1,1,0,0;
    0,0,1,0;
    1,0,0,1];
[m,~]=size(M) %以上应该是题目给的,这里我用于测试

arr=zeros(1,m) %存储元素是否使用状况,0意为未录入,1意为已录入
block=[] %用于存储一个block全部元素
output='划分为:'
for i=1:m
    if arr(i)==0 %如果没被录入就进行录入,因为每个block彼此无交集
        for j=i:m %用于遍历下三角矩阵
            if M(j,i)==1 %如果满足关系,则录入
                block(end+1)=A(j); 
                arr(j)=1; %更新录入状态为1
            end
        end
        output=block %输出每个block
        block=[]; %清空block以便承载下一个block
    end
end        

以下为输出结果
在这里插入图片描述

找寻LUB和GLB

给定一个非空有限偏序集(A,≤),设计算法求解A中任意两个元素最小上边界存储在矩阵MLUB中,设计算法求解A中任意两个元素最大下边界,存储在矩阵MGLB中。

思路

这里要用到一个推论(证明很简单,我就不证了)
a∨b=b,当且仅当a≤b
a∧b=a,当且仅当a≤b
所以遍历整个集合A
对每个元素i,再遍历集合A一次
用A(i)对比A(j),如果满足A(i)≤ A(j),则A(i)存入MGLB中第(i,j)位,A(j)存入MLUB第(i,j)位。
输出MLUB 和 MGLB

伪代码如下:

Input 集合A
求出A的模m
for i=1:m
	for j=1:m
		if A(i)和A(j)满足≤关系
			GLB(i,j)=A(i)
			LUB(i,j)=A(j)
		end if
	end for
end for
Output GLB 和 LUB

MATLAB代码

clc
clear all

A=[1,2,3,4]
[~,m]=size(A)
GLB=zeros(m,m)
LUB=zeros(m,m)
for i=1:m
    for j=1:m
        if A(i)<=A(j)
            GLB(i,j)=A(i);
            LUB(i,j)=A(j);
        end 
    end
end
output=GLB
output=LUB

以下为输出结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值