package pkg1;
/*This is the starting file*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

/*
 * get a hashtable -- seq:element list
 * get a hashtable -- element: seq list it belongs to
 */
public class getPagesNo {
	
	public static int webCount;
	/*
	 * This function creates the hashtable for each page: ID(0,1,2...) for each one as value. e.g. page12419:55;
	 * just in case the file read by loadFileWebViewFormat contains random numbers, so normalize them from 0-n
	 */
	public HashMap<Integer, Integer> getpageNo(ArrayList<ArrayList<Integer>> s) {
		//use a hash table to store each pages' number and its create an ID for it as value
		HashMap<Integer, Integer> hashP = new HashMap<Integer, Integer>();
		this.webCount = 0;
		for(ArrayList<Integer> current: s)
		{
			for(int i: current)
			{
				if(!hashP.containsKey(i)) 
					hashP.put(i, webCount++); 
			}
		}
		//System.out.println(count);//total number of pages
		//ArrayList<Integer> pages = new ArrayList<Integer>(hashP.keySet());
		return hashP;
	}
	/*
	 * returns the hashtable showing which pages in each seq, e.g. seq1: p1,p2,p3, %%the page number is the original number
	 * the parameter "a" is from loadFileWebViewFormat.java
	 */
	public HashMap<Integer, ArrayList<Integer>> seqHashOrig(ArrayList<ArrayList<Integer>> a )
	{		
		int i;
		HashMap<Integer, ArrayList<Integer>> seqHs = new HashMap<Integer, ArrayList<Integer>>();
		for(i = 0 ; i < a.size(); i++)
		{ 
			seqHs.put(i, a.get(i));
		}
		return seqHs;
	}
	/*
	 * returns the hashtable showing which pages in each seq, e.g. seq1: p1,p2,p3, %%the page number is the simplified one using getpageNo
	 */
	public HashMap<Integer, ArrayList<Integer>> seqHash(ArrayList<ArrayList<Integer>> a, HashMap<Integer, Integer> p)
	{
		int i, j ;
		HashMap<Integer, ArrayList<Integer>> seqHs = new HashMap<Integer, ArrayList<Integer>>();
		for(i = 0 ; i < a.size(); i++)
		{ 
			ArrayList<Integer> tmp = new ArrayList<Integer>();
			for(j=0; j < a.get(i).size(); j++)
				tmp.add(p.get(a.get(i).get(j)));
			seqHs.put(i, tmp);
		}
		return seqHs;
	}
	/*
	 * findTopSingle() finds the top  frequent single categories whose visitings are > n
	 */
	public HashMap<Integer, Integer> findTopSingle(ArrayList<ArrayList<Integer>> seq, int n)
	{
		HashMap<Integer, Integer> tops = new HashMap<Integer, Integer>();
		HashMap<Integer, Integer> topN = new HashMap<Integer, Integer>();

		for(int i = 0; i < seq.size(); i++)
		{
			for(int j = 0; j < seq.get(i).size();j++)
			{
				if(!tops.keySet().contains(seq.get(i).get(j)))
				{
					tops.put(seq.get(i).get(j), 1);
				}
				else
					tops.put(seq.get(i).get(j), tops.get(seq.get(i).get(j))+1);
			}
		}
		for(Integer eachPage: tops.keySet())
		{
			if(tops.get(eachPage) > n)
				topN.put(eachPage, tops.get(eachPage));
		}
		return topN;
	}
	/*
	 * returns the hashtable showing each page's related seq, e.g. p1: seq1,seq2,seq3, %%the page number is the simplified one using getpageNo
	 */
	public HashMap<Integer, ArrayList<Integer>> eleHash(HashMap<Integer, ArrayList<Integer>> seqhs)
	{
		int i ;
		HashMap<Integer, ArrayList<Integer>> eleHs = new HashMap<Integer, ArrayList<Integer>>();
		
		for(i=0; i < webCount; i++)
		{
			ArrayList<Integer> tmp = new ArrayList<Integer>();
			for(Integer key: seqhs.keySet())
			{
				if(seqhs.get(key).contains(i))
				{
					tmp.add(key);
				}
			}
			eleHs.put(i, tmp);
		}
		return eleHs;
	}
	
	/*
	 * returns the hashtable showing each path's supporting seq, e.g. p1: seq1,seq2,seq3, 
	 * %%the page number is the simplified one using getpageNo
	 * there is a threshold showing how many pages in the seq is in the path, if the seq has pages > threshold in the path
	 * then pick it as a supporting seq
	 * the parameter "a" is the sequence list from loadFileWebViewFormat.java, so need to converted to simplified version
	 * using the hash by getpageNo()
	 * return the Index of the sessions
	 */
	public ArrayList<ArrayList<Integer>> pathSupport(ArrayList<Integer> path, ArrayList<ArrayList<Integer>> a, int threshold)
	{
		int i , j, k;
		ArrayList<ArrayList<Integer>> support = new ArrayList<ArrayList<Integer>>();
		int count;
		i = 0;
		for(j = 0; j < a.size(); j++)
		{
			count = 0;
			k = 0;
			i = 0;
			while((k < a.get(j).size()) && (i < path.size()))
			{
				int x = path.get(i);
				int y = a.get(j).get(k);
				if(x == y)
				{
					i++;k++;
					count++;
				}
				else
				{
					i=0;count = 0;
					k++;
				}
					
				if(count >= threshold)
				{
					support.add(a.get(j));
					break;
				}
			}
		}
		
		return support;
	}
	/*
	 * findTopHop() finds the top frequent one-hop categories with support > n
	 */
	public HashMap<ArrayList<Integer>, Integer> findTopHop(ArrayList<ArrayList<Integer>> seq, int n)
	{
		HashMap<ArrayList<Integer>, Integer> tops = new HashMap<ArrayList<Integer>, Integer>();
		HashMap<ArrayList<Integer>, Integer> topN = new HashMap<ArrayList<Integer>, Integer>();
		for(int i = 0; i < seq.size(); i++)
		{
			for(int j = 0; j < seq.get(i).size()-1; j++)
			{
				ArrayList<Integer> tmp = new ArrayList<Integer>();
				tmp.add(seq.get(i).get(j));
				tmp.add(seq.get(i).get(j+1));
				if(!tops.keySet().contains(tmp))
					tops.put(tmp, 1);
				else
					tops.put(tmp, tops.get(tmp)+1);
			}
		}

		for(ArrayList<Integer> eachPage: tops.keySet())
		{
			if(tops.get(eachPage) > n)
				topN.put(eachPage, tops.get(eachPage));
		}
		return topN;
	}
	/*
	 * findTop2Hop() finds the top frequent 2-hop categories with support > n
	 */
	public HashMap<ArrayList<Integer>, Integer> findTop2Hop(ArrayList<ArrayList<Integer>> seq, int n)
	{
		HashMap<ArrayList<Integer>, Integer> tops = new HashMap<ArrayList<Integer>, Integer>();
		HashMap<ArrayList<Integer>, Integer> topN = new HashMap<ArrayList<Integer>, Integer>();
		for(int i = 0; i < seq.size(); i++)
		{
			for(int j = 0; j < seq.get(i).size()-2; j++)
			{
				ArrayList<Integer> tmp = new ArrayList<Integer>();
				tmp.add(seq.get(i).get(j));
				tmp.add(seq.get(i).get(j+1));
				tmp.add(seq.get(i).get(j+2));
				if(!tops.keySet().contains(tmp))
					tops.put(tmp, 1);
				else
					tops.put(tmp, tops.get(tmp)+1);
			}
		}

		for(ArrayList<Integer> eachPage: tops.keySet())
		{
			if(tops.get(eachPage) > n)
				topN.put(eachPage, tops.get(eachPage));
		}
		return topN;
	}
	/*
	 * findTop3Hop() finds the top frequent 3-hop categories with support > n
	 */
	public HashMap<ArrayList<Integer>, Integer> findTop3Hop(ArrayList<ArrayList<Integer>> seq, int n)
	{
		HashMap<ArrayList<Integer>, Integer> tops = new HashMap<ArrayList<Integer>, Integer>();
		HashMap<ArrayList<Integer>, Integer> topN = new HashMap<ArrayList<Integer>, Integer>();
		for(int i = 0; i < seq.size(); i++)
		{
			for(int j = 0; j < seq.get(i).size()-3; j++)
			{
				ArrayList<Integer> tmp = new ArrayList<Integer>();
				tmp.add(seq.get(i).get(j));
				tmp.add(seq.get(i).get(j+1));
				tmp.add(seq.get(i).get(j+2));
				tmp.add(seq.get(i).get(j+3));
				if(!tops.keySet().contains(tmp))
					tops.put(tmp, 1);
				else
					tops.put(tmp, tops.get(tmp)+1);
			}
		}

		for(ArrayList<Integer> eachPage: tops.keySet())
		{
			if(tops.get(eachPage) > n)
				topN.put(eachPage, tops.get(eachPage));
		}
		return topN;
	}
	
	/*
	 * findTop4Hop() finds the top frequent 4-hop categories with support > n
	 */
	public HashMap<ArrayList<Integer>, Integer> findTop4Hop(ArrayList<ArrayList<Integer>> seq, int n)
	{
		HashMap<ArrayList<Integer>, Integer> tops = new HashMap<ArrayList<Integer>, Integer>();
		HashMap<ArrayList<Integer>, Integer> topN = new HashMap<ArrayList<Integer>, Integer>();
		for(int i = 0; i < seq.size(); i++)
		{
			for(int j = 0; j < seq.get(i).size()-4; j++)
			{
				ArrayList<Integer> tmp = new ArrayList<Integer>();
				tmp.add(seq.get(i).get(j));
				tmp.add(seq.get(i).get(j+1));
				tmp.add(seq.get(i).get(j+2));
				tmp.add(seq.get(i).get(j+3));
				tmp.add(seq.get(i).get(j+4));
				if(!tops.keySet().contains(tmp))
					tops.put(tmp, 1);
				else
					tops.put(tmp, tops.get(tmp)+1);
			}
		}

		for(ArrayList<Integer> eachPage: tops.keySet())
		{
			if(tops.get(eachPage) > n)
				topN.put(eachPage, tops.get(eachPage));
		}
		return topN;
	}
	public static void main(String args[])
	{
		int i;
		loadFileWebViewFormat l = new loadFileWebViewFormat();
		ArrayList<ArrayList<Integer>> seq = l.loadFile("BMS1.dat", 333);//second prm not used anymore
		getPagesNo g = new getPagesNo();
		HashMap<Integer, Integer> p = g.getpageNo(seq); 

/*///////////////////////////////////PATHSUPPORT TEST///////////////////
		ArrayList<Integer> a1 = new ArrayList<Integer>();
	a1.add(1);
	a1.add(2);
	a1.add(3);
	ArrayList<Integer> a2 = new ArrayList<Integer>();
	a2.add(5);
	a2.add(3);   
	 ArrayList<ArrayList<Integer>> x  = new  ArrayList<ArrayList<Integer>>();
	 x.add(a1);
	 x.add(a2);

		ArrayList<Integer> a3 = new ArrayList<Integer>();
		a3.add(1);
		a3.add(2);
		System.out.print(g.pathSupport(a3, x, 1));
/*///////////////////////////////////PATHSUPPORT TEST///////////////////
		//System.out.println(p);
		matrix m = new matrix(); 
		int[][] a = m.createHyperShare(seq, p);
		int[][][] aa = m.initArray(a);
		m.initLenList(aa);
		m.getLenArrayRec(5);
		//System.out.print(m.paths);
		System.out.println();
		ArrayList<ArrayList<Integer>> paths = m.pHashN(2100);
		System.out.print(paths);

		//HashMap<Integer, Integer> tops = g.findTopSingle(seq, 1900);
		HashMap<ArrayList<Integer>, Integer> tops = g.findTop4Hop(seq, 49);
		//print out top visited pages
		for(ArrayList<Integer> eachPage: tops.keySet())
		{
			ArrayList<Integer> tmp = new ArrayList<Integer>();
			for(i = 0 ; i < eachPage.size(); i++)
			{
				tmp.add(p.get(eachPage.get(i)));
				System.out.print(p.get(eachPage.get(i))+",");
			}
			System.out.print("--"+m.totalWeight(tmp));
			System.out.println();
		}
		
		/*
		 * DRAWING PART
		 */
		//m.drawG(a);
		/*///////////////////OPTIMIZED TEST/////////////////
		optiMatrix m = new optiMatrix();
		HashMap<ArrayList<Integer>, Integer> a = m.createHyperShare(seq, p);
		m.initLenList(a);
		HashMap<ArrayList<Integer>, Integer> b = m.getLenArrayRec(4);
		*////////////////////
		
		//m.p3DArray(b);
		//System.out.println();
		//m.pHash();
		//ADL EXPERIMENTS
		//m.createADLA(5);
		//m.pHashN(70);
		//for(i = 0; i < 36; i++)
		{
			//m.pHashN(2000+200*i);
			//System.out.println();
		}
		//m.deviation(2000, 5);
		
		/*/TEST RANDOMIZED GREEDY
		for (i = 5; i < 11; i++)
		{
			for(int w = 2000; w < 5000; w = w + 200)
			{
				optiMatrix mm2 = new optiMatrix();
				HashMap<ArrayList<Integer>, Integer> aa2 = mm2.createHyperShare(seq, p);
				simpleMethodTest s2 = new simpleMethodTest();
				s2.list = s2.hash2list(aa2);
				s2.sortQuick(s2.list); 
				Set<ArrayList<ArrayList<Integer>>> set2 = s2.pathSetUsingProbRepeat1000(s2.list, i, w, 3, 3);
				System.out.print(set2.size());
				System.out.print(" ");
			}
			System.out.println();
		}*/

	}
}
