-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTask3.java
153 lines (141 loc) · 5.29 KB
/
Task3.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
// Copyright 2020
// Author: Matei Simtinică
import java.io.*;
import java.util.*;
/**
* Task3
* This being an optimization problem, the solve method's logic has to work differently.
* You have to search for the minimum number of arrests by successively querying the oracle.
* Hint: it might be easier to reduce the current task to a previously solved task
*/
public class Task3 extends Task {
String task2InFilename;
String task2OutFilename;
public Map<Integer, ArrayList<Integer>> families = new LinkedHashMap<>();
public Map<Integer, ArrayList<Integer>> complementary;
public ArrayList<Integer> maxClique = new ArrayList<>();
public int extended;
public int nodes;
public int lines;
public boolean ok = false;
/**
*
* @param famNumb number of families
* @param families the data structure to be osed for stocking the families' relations
*/
public void inititializeMaps(int famNumb, Map<Integer, ArrayList<Integer>> families){
for( int i = 0; i < famNumb; i++ ){
families.put(i, new ArrayList<>());
}
}
/**
*
* @param families initial graph
* @return complementary graph
*/
public Map<Integer, ArrayList<Integer>> makeComplementary( Map<Integer, ArrayList<Integer>> families ){
Map<Integer, ArrayList<Integer>> newGraph = new LinkedHashMap<>();
inititializeMaps(nodes, newGraph);
for (int i = 0; i < nodes; i ++){
for (int k = 0; k < nodes; k ++){
if (!families.get(i).contains(k) && k != i){
newGraph.get(i).add(k);
}
}
}
return newGraph;
}
/**
*
* @param map a graph
* @return number of edges
*/
public int relationsNumber( Map<Integer, ArrayList<Integer>> map ){
int cnt = 0;
for (int i = 0; i < map.size(); i ++){
cnt += map.get(i).size();
}
cnt = cnt / 2;
return cnt;
}
@Override
public void solve() throws IOException, InterruptedException {
task2InFilename = inFilename + "_t2";
task2OutFilename = outFilename + "_t2";
Task2 task2Solver = new Task2();
task2Solver.addFiles(task2InFilename, oracleInFilename, oracleOutFilename, task2OutFilename);
readProblemData();
complementary = makeComplementary(families);
// the size of the max clique in a grraph can be at most equal to the number of nodes
extended = nodes;
// searching for the largest clique
while (!ok) {
reduceToTask2();
task2Solver.solve();
extractAnswerFromTask2();
extended --;
}
writeAnswer();
}
@Override
public void readProblemData() throws IOException {
Scanner scanner = new Scanner(new File(inFilename));
nodes = scanner.nextInt();
lines = scanner.nextInt();
inititializeMaps(nodes,families);
// reading the initial data and creating the graph
for (int i = 0; i < lines; i ++){
int x = scanner.nextInt();
int y = scanner.nextInt();
families.get(x - 1).add(y - 1);
families.get(y - 1).add(x - 1);
}
}
public void reduceToTask2() throws IOException {
// I reduce the problem to task2 by writing the input file containing
// the complementary graph and the size of the clique I am looking for
File file = new File(task2InFilename);
FileWriter fileWriter = new FileWriter(file);
int relations = relationsNumber(complementary);
fileWriter.write(nodes + " " + relations + " " + extended + "\n");
Map<Integer, ArrayList<Integer>> families2 = new LinkedHashMap<>();
inititializeMaps(nodes, families2);
for (int i = 0; i < nodes; i ++){
for (int j = 0; j < complementary.get(i).size(); j ++) {
if (families2.get(i).size() != complementary.get(i).size() &&
!families2.get(i).contains(complementary.get(i).get(j))) {
int x = i + 1;
int y = complementary.get(i).get(j) + 1;
fileWriter.write(x + " " + y + "\n");
families2.get(i).add(complementary.get(i).get(j));
families2.get(complementary.get(i).get(j)).add(i);
}
}
}
fileWriter.close();
}
public void extractAnswerFromTask2() throws IOException {
// fetting the clique from the task2 result
File file = new File(task2OutFilename);
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = reader.readLine();
if (line.contains("True")){
ok = true;
line = reader.readLine();
String[] numbers = line.split(" ");
for (int i =0; i < numbers.length; i ++){
maxClique.add(Integer.parseInt(numbers[i]) - 1);
}
}
}
@Override
public void writeAnswer() throws IOException {
FileWriter fileWriter = new FileWriter(outFilename);
for (int i = 0; i < nodes; i ++){
if (!maxClique.contains(i)){
fileWriter.write((i + 1) + " ");
}
}
fileWriter.close();
}
}