Skip to content

Commit fba8f5a

Browse files
committed
tournament tree hype!
1 parent 76690b5 commit fba8f5a

File tree

7 files changed

+335
-362
lines changed

7 files changed

+335
-362
lines changed

.idea/workspace.xml

Lines changed: 285 additions & 323 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/java/kds/Simulator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ public int run(boolean visualize, boolean auditEveryTimestep) throws IOException
114114
for (EventType e : es) {
115115
if (e.isValid()) {
116116
event = true;
117-
kds.process(e);
118117
LOGGER.log(Level.FINER, "EVENT at time t={0}", e.getFailureTime());
118+
kds.process(e);
119119
}
120120
}
121121
}

src/main/java/tournament_tree/DistanceFunction.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ public void setP(P p) {
2121
}
2222

2323
@Override
24-
public P findWinner(P first, P second) {
24+
public P findWinner(double t, P first, P second) {
25+
p.updatePosition(t);
26+
first.updatePosition(t);
27+
second.updatePosition(t);
2528
double firstDistance = p.getDistance(first);
2629
double secondDistance = p.getDistance(second);
2730
if (Math.abs(firstDistance - secondDistance) < 1e-10) System.out.println("FUCK");
@@ -31,6 +34,7 @@ public P findWinner(P first, P second) {
3134
@Override
3235
public double computeValue(double t, Primitive primitive) {
3336
p.updatePosition(t);
37+
primitive.updatePosition(t);
3438
return p.getDistance(primitive);
3539
}
3640
}

src/main/java/tournament_tree/TournamentEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void computeFailureTime(EigenSolver solver, double t) {
5858
double[] p2_coeffs = getDistCoeffs(winnerFunction.getP().getCoeffsX(), winnerFunction.getP().getCoeffsY(),
5959
bCoeffsX, bCoeffsY);
6060

61-
double[] coeffs = Polynomial.subtract(p2_coeffs, p1_coeffs);
61+
double[] coeffs = Polynomial.subtract(p1_coeffs, p2_coeffs);
6262

6363
try {
6464
double failureTime = Polynomial.findFirstRoot(coeffs, t, this.inFailedEvent);

src/main/java/tournament_tree/TournamentTree.java

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public TournamentTree(double t, ArrayList<P> leaves, TournamentTreeWinner<P> win
4444
public boolean audit(double t) {
4545
ArrayList<Double> distances = new ArrayList<>();
4646
for (TournamentNode<P> leaf : leaves) {
47-
leaf.getWinner().updatePosition(t);
4847
distances.add(winnerFunction.computeValue(t, leaf.getWinner()));
4948
}
5049
Collections.sort(distances);
@@ -59,6 +58,10 @@ public boolean audit(double t) {
5958
valid = false;
6059
LOGGER.info("The tree itself is not valid :(");
6160
}
61+
if (!root.getParent().isNull()) {
62+
valid = false;
63+
LOGGER.info("The root is not the root :(");
64+
}
6265
return valid;
6366
}
6467

@@ -72,10 +75,10 @@ public boolean validate(TournamentNode<P> node) {
7275
if (!valid) return false; // no need to check, TODO print out offenders
7376

7477
if (!node.getLeftChild().isNull()) {
75-
valid = node.getLeftChild().getKey() < node.getKey() && isBalanced(node.getLeftChild(), node);
78+
valid = node.getLeftChild().getKey() <= node.getKey() && isBalanced(node.getLeftChild(), node);
7679
}
7780
if (!node.getRightChild().isNull()) {
78-
valid = valid && node.getKey() <= node.getRightChild().getKey() && isBalanced(node.getRightChild(), node);
81+
valid = valid && node.getKey() < node.getRightChild().getKey() && isBalanced(node.getRightChild(), node);
7982
}
8083
return valid;
8184
}
@@ -105,7 +108,7 @@ public void process(TournamentEvent<P> event) {
105108
event.getNode().setWinner(event.getNode().getLeftChild().getWinner());
106109
}
107110

108-
event.getNode().createEvent(solver, event.getFailureTime(), winnerFunction, true);
111+
eq.add(event.getNode().createEvent(solver, event.getFailureTime(), winnerFunction, true));
109112

110113
// percolate
111114
updateWinners(event.getFailureTime(), event.getNode().getParent());
@@ -143,17 +146,17 @@ public void setWinner(TournamentNode<P> winner) {
143146
public TournamentNode<P> insert(double t, int key, P winner) {
144147
if (root == null) {
145148
root = new TournamentNode<>(key, winner);
146-
root.setRightChild(new TournamentNode<>(key, winner));
149+
root.setLeftChild(new TournamentNode<>(key, winner));
147150
return root;
148151
}
149152

150153
// else -- NOTE: I do not use a stack to keep track of the traversed path. It can be done by keeping a parent
151154
// pointer in every node. Requires more space (obviously), but it makes the code nicer imo.
152155
TournamentNode<P> leaf = root;
153156

154-
// find the location to insert, which is always a leaf
157+
// find the location to insert
155158
while (!leaf.isNull()) {
156-
if (key < leaf.getKey()) leaf = leaf.getLeftChild();
159+
if (key <= leaf.getKey()) leaf = leaf.getLeftChild();
157160
else leaf = leaf.getRightChild();
158161
}
159162

@@ -167,22 +170,23 @@ public TournamentNode<P> insert(double t, int key, P winner) {
167170
TournamentNode<P> new_node = new TournamentNode<>(key, winner);
168171
// attach the new node to the leaf node and alter the old leaf node such that it becomes an internal node
169172
// which means the old leaf must be moved down a level and become the new leaf's sibling
170-
if (key < leaf.getKey()) {
171-
// a leaf must always be a right child!
172-
TournamentNode<P> new_inner = new TournamentNode<>(key, winner);
173-
new_inner.setRightChild(new_node);
174-
leaf.setLeftChild(new_inner);
175-
leaf.setRightChild(new TournamentNode<>(leaf.getKey(), leaf.getWinner()));
173+
// that is if it's even a leaf, no guarantee
174+
if (key <= leaf.getKey()) {
175+
if (leaf.isLeaf()) {
176+
// have to create a new inner node since a leaf cannot have any children
177+
TournamentNode<P> new_leaf = new TournamentNode<>(leaf.getKey(), leaf.getWinner());
178+
leaf.setKey(key); // have to replace its key since
179+
leaf.setRightChild(new_leaf);
180+
}
181+
leaf.setLeftChild(new_node);
176182
}
177183
else {
178-
// here we have to swap the keys as we always let inner nodes have the key of its right leaf
179-
// it is safe to do as everything in the left subtree is less than the new key
184+
if (leaf.isLeaf()) {
185+
// have to create a new inner node since a leaf cannot have any children
186+
TournamentNode<P> new_leaf = new TournamentNode<>(leaf.getKey(), leaf.getWinner());
187+
leaf.setLeftChild(new_leaf);
188+
}
180189
leaf.setRightChild(new_node);
181-
// a leaf must always be a right child!
182-
TournamentNode<P> new_inner = new TournamentNode<>(leaf.getKey(), leaf.getWinner());
183-
new_inner.setRightChild(new TournamentNode<>(leaf.getKey(), leaf.getWinner()));
184-
leaf.setLeftChild(new_inner);
185-
leaf.setKey(new_node.getKey());
186190
}
187191
// time to rebalance the tree
188192
rebalance(t, leaf);
@@ -233,7 +237,7 @@ private void updateWinner(double t, TournamentNode<P> node) {
233237
P leftWinner = node.getLeftChild().getWinner();
234238
P rightWinner = node.getRightChild().getWinner();
235239

236-
node.setWinner(winnerFunction.findWinner(leftWinner, rightWinner));
240+
node.setWinner(winnerFunction.findWinner(t, leftWinner, rightWinner));
237241
}
238242

239243
if (node.getEvent() != null) eq.remove(node.getEvent());
@@ -246,7 +250,7 @@ public TournamentNode<P> delete(double t, int key) {
246250

247251
if (node == null) return null;
248252

249-
// should be safe to assume that the doubles match, otherwise I suck
253+
// should be safe to assume that the keys match, otherwise I suck
250254
assert node.getKey() == key;
251255

252256
return delete(t, node);
@@ -318,7 +322,9 @@ private void rebalance(double t, TournamentNode<P> tmp_node) {
318322
rotate_right(t, tmp_node.getRightChild());
319323
rotate_left(t, tmp_node.getLeftChild());
320324
}
321-
} else if (!tmp_node.isLeaf()) {
325+
}
326+
327+
if (!tmp_node.isLeaf()) {
322328
// even if we don't rotate, we have to update the winner certificate
323329
updateWinner(t, tmp_node);
324330
}
@@ -340,8 +346,8 @@ public TournamentNode<P> find(double key) {
340346
else tmp_node = root;
341347

342348
while (!tmp_node.isNull()) {
343-
if (key < tmp_node.getKey()) tmp_node = tmp_node.getLeftChild();
344-
else if (key >= tmp_node.getKey()) tmp_node = tmp_node.getRightChild();
349+
if (key <= tmp_node.getKey()) tmp_node = tmp_node.getLeftChild();
350+
else if (key > tmp_node.getKey()) tmp_node = tmp_node.getRightChild();
345351
else break;
346352
}
347353

@@ -383,7 +389,7 @@ public void rotate_left(double t, TournamentNode<P> node) {
383389
// reset its parent to avoid a weird cycle
384390
newRoot.setParent(null);
385391
// update root
386-
root = newRoot;
392+
this.root = newRoot;
387393
}
388394
newRoot.setLeftChild(node);
389395
// update b's weights and then a's
@@ -392,7 +398,7 @@ public void rotate_left(double t, TournamentNode<P> node) {
392398

393399
// update the winners, we don't let it percolate though as there may be more rotations
394400
if (!node.isLeaf()) updateWinner(t, node);
395-
//updateWinner(t, newRoot);
401+
updateWinner(t, newRoot);
396402
}
397403

398404
public void rotate_right(double t, TournamentNode<P> node) {
@@ -437,7 +443,7 @@ public void rotate_right(double t, TournamentNode<P> node) {
437443
// this means that 'node' is the root and since 'newRoot' is a child of 'node', we have to manually
438444
// reset its parent to avoid a weird cycle
439445
newRoot.setParent(null);
440-
root = newRoot;
446+
this.root = newRoot;
441447
}
442448
newRoot.setRightChild(node);
443449
// process a's weights and then b's
@@ -446,7 +452,7 @@ public void rotate_right(double t, TournamentNode<P> node) {
446452

447453
// process the winners, we don't let it percolate though as there may be more rotations
448454
if (!node.isLeaf()) updateWinner(t, node);
449-
//updateWinner(t, newRoot);
455+
updateWinner(t, newRoot);
450456
}
451457

452458
public TournamentNode<P> predecessor(TournamentNode<P> node) {

src/main/java/tournament_tree/TournamentTreeWinner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Created by clausvium on 28/12/16.
77
*/
88
public interface TournamentTreeWinner<P extends Primitive> {
9-
P findWinner(P first, P second);
9+
P findWinner(double t, P first, P second);
1010
double computeValue(double t, P p);
1111
P getP();
1212
}

src/main/java/tournament_tree/run.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@ public class run {
1818
public static void main(String[] args) throws Exception {
1919
int failedRuns = 0;
2020
int numRuns = 1000;
21+
int numCoeffs = 10;
2122
for (int run = 0; run < numRuns; ++run) {
2223
Random rand = new Random();
2324

24-
KDSPoint p = new KDSPoint(new double[]{0.1, 1.1},
25-
new double[]{0.3, 2.1});
25+
KDSPoint p = new KDSPoint(new double[]{0.1, 0.2, 0.4},
26+
new double[]{0.3, 2, 0.7});
2627
DistanceFunction<KDSPoint> distanceFunction = new DistanceFunction<>(p);
2728
ArrayList<KDSPoint> leaves = new ArrayList<>();
2829

2930
for (int i = 0; i < 100; ++i) {
30-
double[] coeffsX = new double[2];
31-
double[] coeffsY = new double[2];
32-
for (int j = 0; j < 2; ++j) {
31+
double[] coeffsX = new double[numCoeffs];
32+
double[] coeffsY = new double[numCoeffs];
33+
for (int j = 0; j < numCoeffs; ++j) {
3334
coeffsX[j] = 1 + (1 + 1) * rand.nextDouble();//
3435
coeffsY[j] = -1 + (1 + 1) * rand.nextDouble();
3536
}
@@ -41,7 +42,7 @@ public static void main(String[] args) throws Exception {
4142
Simulator<KDSPoint, TournamentEvent<KDSPoint>> simulator = new Simulator<>(tournamentTree, 0, 0.1, 10, Level.ALL);
4243
//simulator.setScene(J2DScene.createJ2DSceneInFrame());
4344
//p.draw(simulator.getScene(), 0);
44-
int error = simulator.run(false, false);
45+
int error = simulator.run(false, true);
4546
if (error != 0) {
4647
++failedRuns;
4748
}

0 commit comments

Comments
 (0)