package gsearch;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeMap;

import misc.Common;
import misc.ComparableLabeledValue;
import misc.ExtToolsDriver;
import misc.IO;
import misc.Visualizer;

import generator.GraphGenerator;
import graph.CompositeGraph;
import graph.Graph;
import graph.LabeledGraph;

public class TopK {
	private CompositeGraph cg;
	
	public TopK(CompositeGraph g_) {
		cg = g_;
	}
	
	public ComparableLabeledValue[] getActualEI(HashMap<Integer,Double> rn, double r, double[] mixture) {
		Graph g = cg.mix(mixture);
		return g.getNodeValueMap(RWR.eilb(g, rn, r, null,null));
	}
	
	public ComparableLabeledValue[] getActualRW(HashMap<Integer,Double> rn, double r, double[] mixture) {
		Graph g = cg.mix(mixture);
		return g.getNodeValueMap(RWR.rwlb(g, rn, r, null,null));
	}
	
	public double[] getLBEI(HashMap<Integer,Double> rn, double r, double[] mixture, HashSet<Integer> K, HashSet<Integer> F) {
		Graph g = cg.mix(mixture);
		return RWR.eilb(g, rn, r,K,F);
	}
	
	public double[] getUBEI(HashMap<Integer,Double> rn, double r, double[] mixture, HashSet<Integer> K, HashSet<Integer> F) {
		Graph g = cg.mix(mixture);
		return RWR.eiub(g, rn, r,K,F);
	}
	
	public static void main(String[] args) throws Exception{
		
		double pc = 0.5;
		int numparts = 2;
		
		
		HashSet<Integer> a = null;
//		Graph g = GraphGenerator.generateRandomWeighted(100, 500, 10, 100);
		Graph g = GraphGenerator.generateScaleFreeWeighted(500, 10, 100);
//		misc.Common.SEP = "\t";
//		Graph g = misc.IO.readGraphEdgeList("/home/petko/data/gsearch/grid/grid.sorted",false);
//		for (int i = 0; i < g.getm(); i++) g.we[i] *= 1000; 
		
		
		//pc = Math.max(pc, 2.0*g.getn()/g.getm());
		System.out.print("PC: " + pc + "\n");
		
		g = g.getLargestConnectedComponent();
		
		ArrayList<String> po = ExtToolsDriver.partitionGraph(g, numparts);
		
		BitSet el = Sparsifier.sparsifyJCLocal(pc, g);
		Graph gl = g.keepEdges(el);
		ArrayList<String> pl = ExtToolsDriver.partitionGraph(gl, numparts);
		pc = gl.getm()*1.0/g.getm();
		
		BitSet eg = Sparsifier.sparsifyJCGlobal(pc, g);
		Graph gg = g.keepEdges(eg);
		ArrayList<String> pg = ExtToolsDriver.partitionGraph(gg, numparts);
		//Visualizer.visualize(gg, a);
		
		
		
		//Visualizer.visualize(el, a);
		
		int k = 10;
		double alpha = 0.1;
//		BitSet er = Sparsifier.sparsifyEItopK(pc, g, k, alpha);
//		Graph gr = g.keepEdges(er);
//		ArrayList<String> pr = ExtToolsDriver.partitionGraph(gr, numparts);
//		//Visualizer.visualize(gr, a);
		
		BitSet er = Sparsifier.sparsifyDynamicK(pc, g, alpha, true);
		Graph gr = g.keepEdges(er);
		ArrayList<String> pr = ExtToolsDriver.partitionGraph(gr, numparts);
		//Visualizer.visualize(gr, a);
		
		BitSet ew = Sparsifier.sparsifyDynamicK(pc, g, alpha,false);
		Graph gw = g.keepEdges(ew);
		ArrayList<String> pw = ExtToolsDriver.partitionGraph(gw, numparts);
		
		System.out.print("PC: " + pc + "\n");
		
		System.out.print("Graph\tNCut\tConductance\n");
		System.out.print("Orig:\t" + Common.avgNCut(po,g) + "\t" + Common.avgConductance(po,g) + "\n");
		System.out.print("Global:\t" + Common.avgNCut(pg,g) + "\t" + Common.avgConductance(pg,g)+ "\n");
		System.out.print("Local:\t" + Common.avgNCut(pl,g) + "\t" + Common.avgConductance(pl,g) + "\n");
		System.out.print("IE-DK:\t" + Common.avgNCut(pr,g) + "\t" + Common.avgConductance(pr,g) + "\n");
		System.out.print("RW-DK:\t" + Common.avgNCut(pw,g) + "\t" + Common.avgConductance(pw,g) + "\n");
		
		System.out.print("\n");
		System.out.print("Loc-Glob: " + Common.jc(el, eg) + "\n");
		System.out.print("Loc-IE: " + Common.jc(el, er) + "\n");
		System.out.print("Glob-IE: " + Common.jc(eg, er) + "\n");
		System.out.print("RW-IE: " + Common.jc(ew, er) + "\n");

		
		System.exit(0);
		
		
		//Graph g = IO.readGraphEdgeList(Common.GSEARCH_DATA_DIR + "test100");
		HashSet<String> remove = new HashSet<String>();
		remove.add("GO:0008150"); remove.add("GO:0005575"); remove.add("GO:0003674");
		LabeledGraph lg = IO.readGraphEdgeListNodeLabeled(Common.GSEARCH_DATA_DIR + "/function_prediction/celegans/edges", 
				   Common.GSEARCH_DATA_DIR + "/function_prediction/celegans/pin_nodes_loc.txt", 20, remove);
		
		TopK qp = new TopK(new CompositeGraph(lg));
		
		HashMap<Integer,Double> ns = new HashMap<Integer, Double>();
		for (int j=0; j < lg.getn(); j++) {
			
			int node = j;
			
			ns.clear();
			ns.put(node, 1.0);
			ComparableLabeledValue[] tm = qp.getActualEI(ns, 0.5, null);
			
			double sum = 0;
			// explore the top neighbors RWR
			System.err.print("RW:\t");
			for (int i = 1; i < 31; i++) {
				sum += lg.lsim(lg.names[node], tm[i].l);
				if (i%5==0) System.err.print(sum/i + "\t");
			}
			System.err.print("\n");
			
			for(ComparableLabeledValue cv: tm) cv.v /= lg.wn[lg.n2i.get(cv.l)];
			Arrays.sort(tm);
			
			sum = 0;
			System.err.print("EI:\t");
			for (int i = 1; i < 31; i++) {
				sum += lg.lsim(lg.names[node], tm[i].l);
				if (i%5==0) System.err.print(sum/i + "\t");
			}
			System.err.print("\n\n");
			
			//ExtToolsDriver.plotDistribution(tm);
			ExtToolsDriver.kill("gnuplot");
		}
	}
	
}
