Apriori频繁模式挖掘算法

import java.io.*;
import java.util.*;

public class Apriori {
	static String filePath = "d:\\3.txt";
	static ArrayList<ArrayList<Integer>> D = new ArrayList<ArrayList<Integer>>();// 事务数据库
	//static HashSet<HashSet<Integer>> D_side = new HashSet<HashSet<Integer>>();
	static HashMap<ArrayList<Integer>, Double> C = new HashMap<ArrayList<Integer>, Double>();// 项目集
	static HashMap<ArrayList<Integer>, Double> L = new HashMap<ArrayList<Integer>, Double>();// 候选集
	static int D_size = 0;
	static double min_support =0.01;// 最小支持度
	//static double min_confident = 0.1;// 最小置信度
	static HashMap<ArrayList<Integer>, Double> L_ALL = new HashMap<ArrayList<Integer>, Double>();//存储所有频繁集合
	static int sum = 0;
    /*public static boolean containsAll_Set_List(HashSet<Integer> c,HashSet<Integer> e) {
        for (Integer m : e) {
            if (!c.contains(m)) 
                return false;
        }

        return true;
 
    }*/
	public static ArrayList<ArrayList<Integer>> getSubsett(ArrayList<Integer> L) {
		if (L.size() > 0) {
			ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
			for (int i = 0; i < Math.pow(2, L.size()); i++) {// 集合子集个数=2的该集合长度的乘方
				ArrayList<Integer> subSet = new ArrayList<Integer>();
				int index = i;// 索引从0一直到2的集合长度的乘方-1
				for (int j = 0; j < L.size(); j++) {
					// 通过逐一位移,判断索引那一位是1,如果是,再添加此项
					if ((index & 1) == 1) {// 位与运算,判断最后一位是否为1
						subSet.add(L.get(j));
					}
					index >>= 1;// 索引右移一位
				}
				result.add(subSet); // 把子集存储起来
			}
			result.remove(L);
			return result;
		} else {
			return null;
		}
	}
//排序函数
	/*Comparator<ArrayList<Integer>> myComparator = new Comparator<ArrayList<Integer>>() {
		
		@Override
		public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
			Collections.sort(o1);
			Collections.sort(o2);
			int leng = 1;
			while(leng<=o1.size()&&leng<=o2.size()) {
				if(o1.get(leng-1)-o2.get(leng-1)!=0) {
					return o1.get(leng-1)-o2.get(leng-1);
				}else {
					leng++;
				}
			}
			if((leng-1)==o1.size()&&(leng-1)==o2.size()) {
				return 0;
			}
			else {
				return o1.size()-o2.size();
			}
		}
	};*/
//所有子集
	public static ArrayList<ArrayList<Integer>> getSubset(ArrayList<Integer> L) {
		if (L.size() > 0) {
			ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
			for (int i = 0; i < Math.pow(2, L.size()); i++) {// 集合子集个数=2的该集合长度的乘方
				ArrayList<Integer> subSet = new ArrayList<Integer>();
				int index = i;// 索引从0一直到2的集合长度的乘方-1
				for (int j = 0; j < L.size(); j++) {
					// 通过逐一位移,判断索引那一位是1,如果是,再添加此项
					if ((index & 1) == 1) {// 位与运算,判断最后一位是否为1
						subSet.add(L.get(j));
					}
					index >>= 1;// 索引右移一位
				}
				result.add(subSet); // 把子集存储起来
			}
			result.remove(L);
			return result;
		} else {
			return null;
		}
	}
//判断子集是否频繁
	public static boolean IF_Son(ArrayList<ArrayList<Integer>> k) {
		ArrayList<Integer> sub = new ArrayList<Integer>();
		k.remove(sub);
		boolean flagg = true;
		for(ArrayList<Integer> te : k) {
			if(!L_ALL.keySet().contains(te)) {
				flagg = false;
				break;
			}
		}
		return flagg;
	}
//判等函数
	public static boolean Comparex (int t,ArrayList<Integer> k1,ArrayList<Integer> k2) {
		boolean flag = true;
		for(int i=0;i<t-1;i++) {
			if(k1.get(i)!=k2.get(i)) {
				flag = false;
				break;
			}
		}
		return flag;
	}
// 两个整数集求并集
	public static ArrayList<Integer> arrayListUnion( ArrayList<Integer> arraylist1, ArrayList<Integer> arraylist2) {
		ArrayList<Integer> arraylist = new ArrayList<Integer>();
		arraylist.addAll(arraylist1);
		arraylist.addAll(arraylist2);
		arraylist = new ArrayList<Integer>(new HashSet<Integer>(arraylist));
		return arraylist;
	}
	
// 剪枝,删去C少于最小支持度的元素,形成L
	public static void pruning(HashMap<ArrayList<Integer>, Double> C, HashMap<ArrayList<Integer>, Double> L) {
		L.clear();
		// 根据项目集生成候选集
		L.putAll(C);
		// 删除少于最小支持度的元素

		ArrayList<ArrayList<Integer>> temp_delete = new ArrayList<ArrayList<Integer>>(L.keySet());
		for(int i=0;i<temp_delete.size();i++) {
			if(L.get(temp_delete.get(i))<min_support)
				L.remove(temp_delete.get(i));
		}
		System.out.println(L.size());
		System.out.println("Arrive3");
		L_ALL.putAll(L);
		//System.out.println(L.size());
		/*if(L.size()!=0) {
		for(int i=D.size()-1;i>=0;i--) {
			boolean fla = true;
			ArrayList<ArrayList<Integer>> yy = new ArrayList<ArrayList<Integer>>(L.keySet());
			for(int j=0;j<yy.size();j++) {
				if(D.get(i).containsAll(yy.get(j))) {
					fla = false;break;
				}
			}
			if(fla==true) D.remove(i);
		}
		}*/
	}
	
//循环求Lk(K>=2)的频繁项集并返回
	public static HashMap<ArrayList<Integer>, Double> iteration( HashMap<ArrayList<Integer>, Double> C,HashMap<ArrayList<Integer>, Double> L) {
		HashMap<ArrayList<Integer>, Double> L_temp = new HashMap<ArrayList<Integer>, Double>();// 用于判断是否结束剪枝的临时变量
 
		int t = 1;// 迭代次数
		while (L.size() > 0) {// 一旦被剪枝后剪干净,剪枝之前则是最终要求的结果。
			t++;
			L_temp.clear();
			L_temp.putAll(L);
			// 一、连接步
			C.clear();
			// 1.将L中的项以一定的规则两两匹配
			ArrayList<ArrayList<Integer>> L_key = new ArrayList<ArrayList<Integer>>(L.keySet());
			System.out.println("Arrive1");
			Collections.sort(L_key,new Comparator<ArrayList<Integer>>() {//进行排序
				@Override
				public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
					int leng = 1;
					while(leng<=o1.size()&&leng<=o2.size()) {
						if(o1.get(leng-1)-o2.get(leng-1)!=0) {
							return o1.get(leng-1)-o2.get(leng-1);
						}else {
							leng++;
						}
					}
					if((leng-1)==o1.size()&&(leng-1)==o2.size()) {
						return 0;
					}
					else {
						return o1.size()-o2.size();
					}
				}
			});
			//System.out.println(L_key);
			for (int i = 0; i < L_key.size(); i++) {
				for (int j = i + 1; j < L_key.size(); j++) {
					if(Comparex(t-1, L_key.get(i), L_key.get(j))) {
					ArrayList<Integer> C_item = new ArrayList<Integer>();
					C_item = new ArrayList<Integer>(arrayListUnion(L_key.get(i),L_key.get(j)));
					//if (C_item.size() == t) {
						C.put(C_item, 0.0);// 频繁项集的所有非空子集都必须是频繁的
					//}
					}else break;
				}
			}System.out.println("Arrive4");
			//修剪
			ArrayList<ArrayList<Integer>> temp_L = new ArrayList<ArrayList<Integer>>(C.keySet());
			for(int i=0;i<temp_L.size();i++) {
				if(!IF_Son(getSubset(temp_L.get(i)))) {
					C.remove(temp_L.get(i));
				}
			}
			
			System.out.println("Arrive5");
			// 2.通过扫描D,计算此项的支持度
			for (ArrayList<Integer> key : C.keySet()) {
				for (int i = 0; i < D.size(); i++) {
					//HashSet<Integer> pp1 = new HashSet<Integer>(D.get(i));
					//HashSet<Integer> pp2 = new HashSet<Integer>(key);
					//if (pp1.containsAll(pp2)) {
					//if(containsAll_Set_List(new HashSet<Integer>(D.get(i)), new HashSet<Integer>(key))) {
					if(D.get(i).containsAll(key)) {
						C.put(key, C.get(key) + 1.0 / D_size);
					}
				}
			}
System.out.println("Arrive6");
			// System.out.println(C);
			// 二、剪枝步
			pruning(C, L);
			// System.out.println(L);
			// System.out.println("===");
			
		}
		
		return L_temp;
	}
 
	public static void main(String[] args) {
		ArrayList<ArrayList<String>> T = new ArrayList<ArrayList<String>>();
		try {
			Scanner scanner = new Scanner(new File(filePath));	//指定读入文件
			while(scanner.hasNext()) {
				T.add(new ArrayList<String>(Arrays.asList(scanner.nextLine().split(" "))));
			}
			scanner.close();
		}catch (FileNotFoundException e) {
			// TODO: handle exception
			System.out.println("文件不存在,请重新输入");
		}
		int num ;	
		for(int i=0;i<T.size();i++) {
			ArrayList<Integer> te= new ArrayList<Integer>();
			for(int j=0;j<T.get(i).size();j++) {
				num = Integer.valueOf(T.get(i).get(j));
				te.add(num);
			}
			D.add(new ArrayList<Integer>(te));
			te.clear();
		}long start=System.currentTimeMillis();
		/* int mxaa=-1;int ii=0;int jj=0;
			for(int i=0;i<D.size();i++) {
				for(int j=0;j<D.get(i).size();j++) {
					if(D.get(i).get(j)>mxaa) {mxaa=D.get(i).get(j);
					ii=i;jj=j;
					}
				}
			}System.out.print(mxaa+" "+ii+" "+jj);*/
		D_size = D.size();
		// 扫描事务数据库。生成项目集,支持度=改元素在事务数据库出现的次数/事务数据库的事务数
		for (int i = 0; i < D.size(); i++) {
			for (int j = 0; j < D.get(i).size(); j++) {
				int e =  D.get(i).get(j) ;
				ArrayList<Integer> item = new ArrayList<Integer>(Arrays.asList(e));
				if (!C.containsKey(item)) {
					C.put(item, 1.0 / D_size);
				} else {
					C.put(item, C.get(item) + 1.0 / D_size);
				}
			}
		}

		pruning(C, L);// 剪枝
		
		/*
		 * System.out.println(D); System.out.println(C); System.out.println(L);
		 * System.out.println("===");
		 */

		L = iteration(C, L);


		//System.out.println(L_ALL);
		System.out.println("频繁项集总数:"+L_ALL.size());
		 //System.out.println("===");
		long end=System.currentTimeMillis(); 
		System.out.println("程序运行时间: "+(end-start)+"ms");

	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值