-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMaxClique.java
209 lines (188 loc) · 7.07 KB
/
MaxClique.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import java.util.*;
/**
* Randomized Heuristic for the Maximum Clique Problem
*
* @author Shalin Shah
* Email: shah.shalin@gmail.com
*/
public class MaxClique
{
public static void main(String [] args) throws Exception
{
if(args.length == 0)
{
System.out.println("Usage: java MaxClique <DIMACS File Name> <Number of Iterations>");
System.exit(0);
}
Constants.FILE = args[0];
Constants.CLIQUE_ITERATIONS = Integer.parseInt(args[1]);
System.out.println("Reading Graph...");
/* Read the graph from Constants.FILE */
Graph graph = GraphReader.readGraph();
/* The global best clique found so far */
LinkedHashSet gBest = new LinkedHashSet();
System.out.println("Computing Clique...");
long start = System.currentTimeMillis();
/* Construct an initial Clique only based on the degrees of the nodes */
graph.sortList();
Node [] nodes = graph.getSortedNodes();
Clique clique = new Clique(nodes[0].value, graph);
List sList = clique.computeSortedList();
Iterator ittt = sList.iterator();
while(clique.pa.size() > 0)
{
SortedListNode node = (SortedListNode)ittt.next();
if(clique.pa.contains(node.node))
{
clique.addVertex(node.node);
}
}
//System.out.println(clique.clique.size());
gBest.addAll(clique.clique);
int prevBest = clique.clique.size();
int count = 0;
int [] restarts = new int[Constants.NUMBER_NODES];
for(int i=0; i<Constants.CLIQUE_ITERATIONS; i++)
{
//System.out.println(gBest.size());
if(prevBest == gBest.size())
{
count++;
if(count > Constants.TOLERANCE)
{
//randomRestart(clique, graph, restarts);
count = 0;
}
}
else
{
prevBest = gBest.size();
count = 0;
}
/* Choose two vertices randomly and remove from the clique */
int rand1 = (int)(Math.random() * (double)clique.clique.size());
int vertex1 = ((Integer)clique.cliqueList.get(rand1)).intValue();
int rand2 = (int)(Math.random() * (double)clique.clique.size());
int vertex2 = ((Integer)clique.cliqueList.get(rand2)).intValue();
while(rand1 == rand2)
{
rand2 = (int)(Math.random() * (double)clique.clique.size());
vertex2 = ((Integer)clique.cliqueList.get(rand2)).intValue();
}
clique.removeVertex(vertex1);
clique.removeVertex(vertex2);
/* Add vertices to the clique based on the sorted possible additions TreeSet */
if(clique.pa.size() > 0)
{
List sortedList = clique.computeSortedList();
Iterator itt = sortedList.iterator();
while(clique.pa.size() > 0)
{
SortedListNode node = (SortedListNode)itt.next();
if(clique.pa.contains(new Integer(node.node)))
{
clique.addVertex(node.node);
}
}
}
else
{
System.out.println("Should Not Come Here!");
System.exit(1);
}
//System.out.println("PA: " + clique.pa.size());
/* If the new clique is better than the current global best,
* replace the global best with this clique
*/
if(clique.clique.size() > gBest.size())
{
gBest = new LinkedHashSet();
gBest.addAll(clique.clique);
}
}
/*
* Finally, try to improve upon the solution
* considering all vertices one by one using 1-OPT moves
*/
int maxClique = gBest.size();
clique.clique = gBest;
clique.cliqueList = new ArrayList();
clique.cliqueList.addAll(clique.clique);
//System.out.println("Randomized Algorithm Clique Size: " + maxClique);
while(true)
{
boolean flag = false;
for(int i=0; i<clique.clique.size(); i++)
{
int vertex = ((Integer)clique.cliqueList.get(i)).intValue();
clique.removeVertex(vertex);
List sortedList = clique.computeSortedList();
Iterator it = sortedList.iterator();
while(clique.pa.size() > 0)
{
// it should always be valid
SortedListNode node = (SortedListNode)it.next();
if(clique.pa.contains(new Integer(node.node)))
{
clique.addVertex(node.node);
}
}
if(clique.clique.size() > maxClique)
{
maxClique = clique.clique.size();
flag = true;
break;
}
}
if(!flag)
{
break;
}
}
gBest = new LinkedHashSet();
gBest.addAll(clique.clique);
System.out.println("Maximum Clique Size Found: " + gBest.size());
System.out.println("Vertices in the Clique:");
for(Iterator it = gBest.iterator(); it.hasNext();)
{
int vertex = ((Integer)it.next()).intValue();
System.out.print(vertex + " ");
}
long end = System.currentTimeMillis();
System.out.println("\n\n" + (end-start) + " milliseconds (excluding I/O).");
}
/*
* Random Restart the current search from a new random starting vertex
*/
public static void randomRestart(Clique clique, Graph graph, int [] restarts)
{
System.out.println("Random Restarting...");
int rand = (int)(Math.random() * (double)Constants.NUMBER_NODES);
int count = 0;
while(restarts[rand] == 1)
{
count++;
if(count > Constants.MAX_UNIQUE_ITERATIONS)
{
break;
}
rand = (int)(Math.random() * (double)Constants.NUMBER_NODES);
}
restarts[rand] = 1;
Clique clq = new Clique(rand, graph);
List sortedList = clq.computeSortedList();
Iterator it = sortedList.iterator();
while(clq.pa.size() > 0)
{
SortedListNode node =(SortedListNode)it.next();
if(clq.pa.contains(new Integer(node.node)))
{
clq.addVertex(node.node);
}
}
clique.clique = clq.clique;
clique.cliqueList = clq.cliqueList;
clique.pa = clq.pa;
clique.sortedPA = clq.sortedPA;
}
}