求属性集的闭包和函数依赖的闭包算法(二)

当当当当~求属性集的闭包和函数依赖的闭包算法第二弹

上次的求属性集的闭包和函数依赖的闭包算法还没写完,只写玩了第一问求指定元素的闭包,今天终于又把第二问求函数依赖F的闭包写完了,先举个例子吧

R=ABC,F={A→B, B→C}, 求F+

解: F+ ={A→Φ,AB→Φ,AC→Φ,ABC→Φ,B→Φ,C→Φ,
A→A,AB→A,AC→A,ABC→A,B→B,C→C,
A→B,AB→B,AC→B,ABC→B,B→C,
A→C,AB→C,AC→C,ABC→C,B→BC,
A→AB,AB→AB,AC→AB,ABC→AB,BC→Φ,
A→AC,AB→AC,AC→AC,ABC→AC,BC→B,
A→BC,AB→BC,AC→BC,ABC→BC,BC→C,
A→ABC,AB→ABC,AC→ABC,ABC→A,BC→BC}


就是这个格式,一开始看到了这个输出我真是被吓到了。。上课时老师说求这个函数依赖的闭包问题是一个NP问题,从上面我们就可以看出来了,其中求的时候包括了很多次的求子集,求一个集合的全部子集,这听上去就有点恐怖啊,假如说一个集合有10个元素,那这个集合的子集就是2^10的也就是1024个,这是一个指数级,也就是有N个元素的话就是有2^N个子集,哈哈,好多啊。但是还是最终把程序写出来了。


我这个程序的思路很简单,但也许可能比较繁琐,若你们谁有更好的方法介绍一下吧!好了,现在就先说说这个程序的思路吧。


首先,在上一篇(一)中的成果下,我们能够求出相应的元素的闭包,然后再添加几个函数就行,其中一个是求子集函数,就是将一个集合的子集全部求出来,我用的是将个数转换为二进制如0001,0010....来分辨不同的元素,进而求出子集,这个方法可能有点繁琐,但将就用用还是可以的。另一个就是输出函数了,具体的在代码中有比较详细的注释。


下面就是代码部分啦,用java写的,当然也可以用其他语言写,如python之类的写也比较简单。(代码写的时候没怎么规划,想到点就写点,主函数有点多,但还好啦)

import java.util.*;


public class Closures {
	
	public void introduction()
	{
		System.out.println("使用方法说明:");
		System.out.println("输入集合时就可以直接abcdefg...的输入");
		System.out.println("闭包依赖的输入格式为a->b然后回车,再输入c->d,以此类推");
		System.out.println("集合中的空集以@代替");
		System.out.println("-----------------------------------------");
		
	}
	
	public void inputList(List list)//输入总的集合元素
	{
		System.out.println("请输入你的属性列,输入end结束");
		Scanner in=new Scanner(System.in);
		while(in.hasNext())
		{
			String str=in.nextLine();
			if(str.toLowerCase().equals("end"))
			{
				break;
			}
			for(int i=0;i"+name);
		}
	}
	
	public String add(String name,String result)//无重复的添加元素到result中
	{
		String str=result;
		for(int i=0;i=0;i--,j--)
		{
			temp[i]='0';
			if(j>=0&&binary.charAt(j)=='1')
			{
				temp[i]='1';
				flag=false;
			}
			
		}
		for(int i=0;i");//分割字符串将符号左边的放入KEY,右边的放入VALUE
			if(s.length==2){
				map.put(s[0].toUpperCase(), s[1].toUpperCase());//将每个函数依赖以值对的形式存入HashMap中
				rely++;
			}
		}
		Clo.printout(map);//输入依赖关系
		System.out.println("请输入所要求的闭包!输入end结束输入");
		while(true)//输入所求的闭包
		{
			Scanner in=new Scanner(System.in);
			result=in.nextLine().toUpperCase();
			if(result.toLowerCase().equals("end"))
			{
				break;
			}
			result=Clo.calculate(result,map);//计算所求的闭包
			System.out.println("所要求的闭包为:"+result);
		}
		
		//求函数依赖的闭包
		result=Clo.outputList(list);//过去开始输入的集合
		int length=(int)Math.pow(2.0, result.length());//计算集合一共有多少个子集
		String str[]=new String[length];//用来存储字符
		Clo.calculateSet(result,str);
		for(int i=0;i"+substr[j]);//输出
			}
		}
		
		
	}
}



你可能感兴趣的:(java)