-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolver.java
More file actions
189 lines (159 loc) · 6.41 KB
/
Copy pathsolver.java
File metadata and controls
189 lines (159 loc) · 6.41 KB
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
import java.util.BitSet;
import java.util.Random;
public class solver {
// Max runtime
private final static int T = 10000000;
static int numVars;
static int numClauses;
static int[] clauseCosts;
static int[] currentCosts;
static int[] literals;
static int[] values;
static BitSet vars;
public static void main(String[] args) {
Random random = new Random();
// Read in wcard file
CapstoneFileReader reader = new CapstoneFileReader();
reader.InitializeClauses("test.txt", false);
// Get data from reader
numVars = reader.getNumVars();
numClauses = reader.getNumClauses();
clauseCosts = reader.getCosts();
currentCosts = new int[numClauses]; // initialise current cost list
literals = reader.getLiterals();
values = reader.getValues();
// Boolean variables
vars = new BitSet(numVars);
// Set up boolean assignment
for (int i=0; i < numVars; i++)
{
// Initiate boolean assignment randomly
if (random.nextInt(2) == 1)
{
vars.set(i);
}
}
// Define 2d array to link variables to clauses
int[][] clauses = new int[numVars][numClauses];
// Link variables to clauses
for (int i=0; i < numClauses; i++)
{
for (int j=0; j < numVars; j++)
{
clauses[j][i] = (literals[numVars*i+j] == 0) ? 0 : 1;
}
}
// Calculate cost of initial state
int curCost = 0;
for (int i=0; i < numClauses; i++)
{
currentCosts[i] = calcCurrentClauseCost(i);
curCost = curCost + currentCosts[i];
}
System.out.println("Initial cost: " + (Integer.toString(curCost))); ///
// Record overall best assignment and best score
BitSet bestAssignment = new BitSet(numVars);
int bestScore = Integer.MAX_VALUE;
// Create new int array to store updated costs for each clause
int[] updatedCosts = new int[numClauses];
int t = 0;
int minCost;
int minCostFlip;
int tempCost = 0;
while (true)
{
// for each variable:
// flip, then update cost for affected clauses
// sum to get "total cost of flip"
minCost = curCost; // for each pass, reset the min cost, and corresponding variable flip
minCostFlip = -1;
for (int i=0; i<numVars; i++)
{
// flip var
vars.flip(i);
tempCost = 0;
// recalculate cost of hypothetical scenario
for (int j=0; j < numClauses; j++)
{
// If the current clause must be checked (i.e. has been affected by a flip), then update cost
updatedCosts[j] = (clauses[i][j] == 1) ? calcCurrentClauseCost(j) : currentCosts[j];
tempCost = tempCost + updatedCosts[j];
}
vars.flip(i); // flip var back
// take min to get which flip results in lowest cost
if (tempCost < minCost)
{
minCost = tempCost;
minCostFlip = i;
}
t++;
}
// Check if no improvements made, then restart with random assignments
if (minCostFlip == -1)
{
if (minCost < bestScore)
{
bestScore = minCost;
bestAssignment = (BitSet)vars.clone();
System.out.println("New Best Cost: " + Integer.toString(bestScore));
}
if (t > T) {break;} // if time is up, end run
// Assuming time isn't up - restart algorithm with randomly assigned vars
for (int i=0; i < numVars; i++)
{
// Initiate boolean assignment randomly
if (random.nextInt(2) == 1)
{
vars.set(i);
}
}
minCostFlip = random.nextInt(numVars);
}
// flip variable and update clauses if it results in an improvement
vars.flip(minCostFlip);
// recalculate cost of current scenario
curCost = 0;
for (int j=0; j < numClauses; j++)
{
// If the current clause must be checked (i.e. has been affected by a flip), then update cost
currentCosts[j] = (clauses[minCostFlip][j] == 1) ? calcCurrentClauseCost(j) : currentCosts[j];
curCost = curCost + currentCosts[j];
}
//if (t > T) {break;} // if time is up, end run
}
System.out.println("Final Best Cost: " + Integer.toString(bestScore));
// Create string output
//String output = "(";
//for (int k=0; k < numVars-1; k++)
//{
// output = output + ((bestAssignment.get(k)) ? "1" : "0") + ", ";
//}
//output = output + ((bestAssignment.get(numVars-1)) ? "1" : "0") + ")";
//System.out.println("Corresponding Assignment: " + output);
}
public static boolean checkSAT(int clauseToCheck)
{
int sum = 0;
// Loop over each variable that could occur in clause (all vars)
for (int i=0; i < numVars; i++)
{
// If a positive literal is mentioned, check if it is set, and if so, add to total value on LHS of expression
if (literals[numVars*clauseToCheck+i] > 0)
{
sum = sum + ((vars.get(i)) ? 1 : 0);
}
// If a negative literal is mentioned, check if it is NOT set, and if not, add to total value on LHS of expression
else if (literals[numVars*clauseToCheck+i] < 0)
{
sum = sum + ((vars.get(i)) ? 0 : 1);
}
// If the literal is 0, don't consider it (no "else" needed)
}
return (sum >= values[clauseToCheck]); //return whether the accumulated sum is geq the related value
}
public static int calcCurrentClauseCost(int clause)
{
// If clause is satisfied, cost is 0, otherwise return associated cost
return (checkSAT(clause)) ? 0 : clauseCosts[clause];
}
}