1 | |
---|
2 | package clustering; |
---|
3 | |
---|
4 | import edu.uci.ics.jung.algorithms.scoring.PageRank; |
---|
5 | import edu.uci.ics.jung.algorithms.scoring.PageRankWithPriors; |
---|
6 | import edu.uci.ics.jung.graph.Graph; |
---|
7 | import java.util.ArrayList; |
---|
8 | import java.util.Collection; |
---|
9 | import java.util.Collections; |
---|
10 | import java.util.Iterator; |
---|
11 | import java.util.List; |
---|
12 | import org.apache.commons.collections15.Transformer; |
---|
13 | |
---|
14 | |
---|
15 | public class LocalSpectral<V,E> { |
---|
16 | |
---|
17 | Graph<V,E> graph; |
---|
18 | |
---|
19 | double alpha = 0.15; |
---|
20 | |
---|
21 | public Graph<V, E> getGraph() { |
---|
22 | return graph; |
---|
23 | } |
---|
24 | |
---|
25 | public void setGraph(Graph<V, E> graph) { |
---|
26 | this.graph = graph; |
---|
27 | } |
---|
28 | |
---|
29 | public LocalSpectral(Graph<V,E> input){ |
---|
30 | graph = input; |
---|
31 | } |
---|
32 | |
---|
33 | public void removeCutEdges(List<V> cut){ |
---|
34 | for(V vertex : cut){ |
---|
35 | Collection<E> out_edges = graph.getOutEdges(vertex); |
---|
36 | for(E edge : out_edges){ |
---|
37 | V opposite_vertex = graph.getOpposite(vertex, edge); |
---|
38 | if (!cut.contains(opposite_vertex)){ |
---|
39 | graph.removeEdge(edge); |
---|
40 | } |
---|
41 | } |
---|
42 | } |
---|
43 | |
---|
44 | } |
---|
45 | |
---|
46 | public List<VertexScore<V>> getGlobalRank(){ |
---|
47 | PageRankWithPriors rank; |
---|
48 | rank = new PageRank(graph, alpha); |
---|
49 | rank.evaluate(); |
---|
50 | Collection<V> vertexs = graph.getVertices(); |
---|
51 | Iterator<?> vertexsIterator = vertexs.iterator(); |
---|
52 | ArrayList<VertexScore<V>> vertexsScore = new ArrayList<VertexScore<V>>(); |
---|
53 | while(vertexsIterator.hasNext()){ |
---|
54 | V vertex = (V) vertexsIterator.next(); |
---|
55 | Double score = (Double) rank.getVertexScore(vertex); |
---|
56 | VertexScore<V> vertexscore = new VertexScore<V>(vertex,score); |
---|
57 | vertexsScore.add(vertexscore); |
---|
58 | } |
---|
59 | |
---|
60 | Collections.sort(vertexsScore,new VertexScoreComparator()); |
---|
61 | return vertexsScore; |
---|
62 | } |
---|
63 | |
---|
64 | public List<V> clusterPageRankPriors(V seed, double min_volume){ |
---|
65 | PageRankWithPriors rank; |
---|
66 | if(seed != null){ |
---|
67 | Transformer transf = new SeedTransformer(seed); |
---|
68 | rank = new PageRankWithPriors(graph, transf, alpha); |
---|
69 | } |
---|
70 | else{ |
---|
71 | rank = new PageRank(graph, alpha); |
---|
72 | } |
---|
73 | |
---|
74 | rank.evaluate(); |
---|
75 | Collection<V> vertexs = graph.getVertices(); |
---|
76 | Iterator<?> vertexsIterator = vertexs.iterator(); |
---|
77 | ArrayList<VertexScore<V>> vertexsScore = new ArrayList<VertexScore<V>>(); |
---|
78 | while(vertexsIterator.hasNext()){ |
---|
79 | V vertex = (V) vertexsIterator.next(); |
---|
80 | Double score = (Double) rank.getVertexScore(vertex); |
---|
81 | int degree = graph.getIncidentEdges(vertex).size(); |
---|
82 | VertexScore<V> vertexscore = new VertexScore<V>(vertex,score/degree); |
---|
83 | vertexsScore.add(vertexscore); |
---|
84 | } |
---|
85 | |
---|
86 | Collections.sort(vertexsScore,new VertexScoreComparator()); |
---|
87 | |
---|
88 | System.out.println("\n\nClustering with prior seed: "+seed.toString()); |
---|
89 | |
---|
90 | int volume_graph = 2 * graph.getEdgeCount(); |
---|
91 | double max_volume = (volume_graph / 3) * 2; |
---|
92 | double min_conductance_subset=100; |
---|
93 | int min_conductance_index = -1; |
---|
94 | int volume_cluster=0; |
---|
95 | |
---|
96 | int subsets_count = vertexsScore.size(); |
---|
97 | for(int i=0; i<subsets_count; i++){ |
---|
98 | int volume_subset = 0; |
---|
99 | ArrayList<V> subset = new ArrayList<V>(); |
---|
100 | for(int j=0; j<i; j++){ |
---|
101 | subset.add(vertexsScore.get(j).getVertex()); |
---|
102 | } |
---|
103 | int edge_boundary = 0; |
---|
104 | for(int j=0; j<i; j++){ |
---|
105 | volume_subset += graph.getIncidentEdges(vertexsScore.get(j).getVertex()).size(); |
---|
106 | for(E out_edge : graph.getOutEdges(vertexsScore.get(j).getVertex())){ |
---|
107 | V opposite = graph.getOpposite(vertexsScore.get(j).getVertex(), out_edge); |
---|
108 | if(!subset.contains(opposite)) |
---|
109 | edge_boundary++; |
---|
110 | } |
---|
111 | } |
---|
112 | if(volume_subset > 0){ |
---|
113 | double minvolume = volume_subset; |
---|
114 | if (volume_subset > (volume_graph - volume_subset)) |
---|
115 | minvolume = volume_graph - volume_subset; |
---|
116 | double conductance = edge_boundary / minvolume; |
---|
117 | |
---|
118 | if ((volume_subset > min_volume) && (volume_subset < max_volume)){ |
---|
119 | //if (volume_subset < min_volume){ |
---|
120 | if (conductance < min_conductance_subset){ |
---|
121 | min_conductance_subset = conductance; |
---|
122 | min_conductance_index = i; |
---|
123 | volume_cluster = volume_subset; |
---|
124 | } |
---|
125 | } |
---|
126 | } |
---|
127 | |
---|
128 | } |
---|
129 | System.out.println("MIN CONDUCTANCE: "+min_conductance_subset); |
---|
130 | |
---|
131 | System.out.println("CLUSTER: ("+min_conductance_index+" elements, volume "+ volume_cluster +", volume graph "+ 2 * this.graph.getEdgeCount()+")"); |
---|
132 | List<V> cluster = new ArrayList<V>(); |
---|
133 | for(int i=0; i< min_conductance_index; i++) |
---|
134 | cluster.add(vertexsScore.get(i).getVertex()); |
---|
135 | |
---|
136 | String node_list = ""; |
---|
137 | for(V node : cluster) |
---|
138 | node_list += node.toString() + ","; |
---|
139 | System.out.println(node_list); |
---|
140 | |
---|
141 | return cluster; |
---|
142 | |
---|
143 | } |
---|
144 | |
---|
145 | } |
---|