Skip to content

Commit

Permalink
Implement the Floyd Warshall algorithm edemo#258
Browse files Browse the repository at this point in the history
  • Loading branch information
szirbucz committed Mar 29, 2019
1 parent 8a05c1e commit 1f2b864
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/main/java/org/rulez/demokracia/pdengine/BeatTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.rulez.demokracia.pdengine.dataobjects.Pair;
import org.rulez.demokracia.types.MapMatrix;

public class BeatTable extends MapMatrix<Choice, Pair> implements ContainingBeats{
public class BeatTable extends MapMatrix<Choice, Pair> implements TransitiveClosable {
private static final long serialVersionUID = 1L;

public enum Direction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ else if (beat1.winning < beat2.winning)
else if (beat2.losing < beat1.losing)
return beat2;
else
throw new UnsupportedOperationException();
return beat1;
}


Expand Down
31 changes: 31 additions & 0 deletions src/main/java/org/rulez/demokracia/pdengine/FloydWarshall.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.rulez.demokracia.pdengine;

import java.util.Collection;

import jersey.repackaged.com.google.common.collect.Sets;

public class FloydWarshall {

private TransitiveClosable beatTable;

public FloydWarshall(final TransitiveClosable beatTable) {
this.beatTable = beatTable;
}

public void computeTransitiveClosure() {
Collection<Choice> keyCollection = beatTable.getKeyCollection();
keyCollection.forEach(i -> keyCollection.forEach(j -> computeMinimalRoute(i, j)));
}

private void computeMinimalRoute(final Choice i, final Choice j) {
if (!i.equals(j)) {
beatTable.getKeyCollection().forEach(k -> selectShorterPath(i, j, k));
}
}

private void selectShorterPath(final Choice i, final Choice j, final Choice k) {
if (!Sets.newHashSet(i, j).contains(k)) {
beatTable.selectShorterPath(i, j, k);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.rulez.demokracia.pdengine;

import org.rulez.demokracia.pdengine.dataobjects.Pair;

import jersey.repackaged.com.google.common.collect.Sets;

public interface TransitiveClosable extends ContainingBeats {

default void computeTransitiveClosure() {
FloydWarshall floydWarshall = new FloydWarshall(this);
floydWarshall.computeTransitiveClosure();
}

default void selectShorterPath(final Choice i, final Choice j, final Choice k) {
if (!Sets.newHashSet(i, j).contains(k)) {
setElement(i, j,
compareBeats(getElement(i, j),
lessBeat(getElement(i, k), getElement(k, j))));
}
}

default Pair lessBeat(final Pair a, final Pair b) {
Pair greater = this.compareBeats(a, b);
return greater.equals(a) ? b : a;
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
package org.rulez.demokracia.pdengine;

import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;
import org.rulez.demokracia.pdengine.annotations.TestedBehaviour;
import org.rulez.demokracia.pdengine.annotations.TestedFeature;
import org.rulez.demokracia.pdengine.annotations.TestedOperation;
import org.rulez.demokracia.pdengine.dataobjects.Pair;
import org.rulez.demokracia.pdengine.exception.ReportedException;
import org.rulez.demokracia.pdengine.testhelpers.CreatedBeatTable;

@TestedFeature("Unimplemented")
@TestedOperation("Unimplemented")
@TestedBehaviour("Unimplemented")
@TestedFeature("Schulze method")
@TestedOperation("compare beats")
@TestedBehaviour("if beats and loses are tie, give back the first option")
public class BeatTableCompareBeatsTieTest extends CreatedBeatTable {

@Override
@Before
public void setUp() throws ReportedException {
super.setUp();
}

@Test
public void compareBeats_is_not_yet_implemented_when_the_result_is_tie() {
assertUnimplemented(() -> beatTable.compareBeats(beats1, beats1));
public void compareBeats_returns_the_first_beat_when_the_result_is_tie() {
Pair beat1 = new Pair(4, 3);
Pair beat2 = new Pair(4, 3);

assertTrue(beatTable.compareBeats(beat1, beat2) == beat1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.rulez.demokracia.pdengine;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Collection;

import org.junit.Before;
import org.junit.Test;
import org.rulez.demokracia.pdengine.annotations.TestedBehaviour;
import org.rulez.demokracia.pdengine.annotations.TestedFeature;
import org.rulez.demokracia.pdengine.annotations.TestedOperation;
import org.rulez.demokracia.pdengine.dataobjects.Pair;
import org.rulez.demokracia.pdengine.exception.ReportedException;
import org.rulez.demokracia.pdengine.testhelpers.CreatedBeatTable;

import jersey.repackaged.com.google.common.collect.Sets;

@TestedFeature("Schulze method")
@TestedOperation("compare beats")
@TestedBehaviour("implements the Floyd-Warshall algorithm")
public class BeatTableTransitiveClosureTest extends CreatedBeatTable {

@Override
@Before
public void setUp() throws ReportedException {
super.setUp();
createNewBeatTableWithComplexData();
}

@Test
public void transitive_closure_on_empty_beat_table_results_empty_result() {
BeatTable actual = new BeatTable();
actual.computeTransitiveClosure();
assertTrue(actual.getKeyCollection().isEmpty());
}

@Test
public void transitive_closure_computes_the_shortest_paths_by_pairs() {
beatTable.computeTransitiveClosure();
Collection<Choice> keyCollection = beatTable.getKeyCollection();
for (Choice i : keyCollection) {
for (Choice j : keyCollection) {
if (i.equals(j)) {
continue;
}
for (Choice k: keyCollection) {
if (Sets.newHashSet(i, j).contains(k)) {
continue;
}
Pair greater = beatTable.getElement(i, j);
Pair less = beatTable.lessBeat(beatTable.getElement(i, k), beatTable.getElement(k, j));
assertEquals(greater, beatTable.compareBeats(less, greater));
}
}
}
}

@Test
public void less_beat_returns_the_less_beat() {
Pair pair1 = new Pair(20, 10);
Pair pair2 = new Pair(10, 10);

Pair lessBeat = beatTable.lessBeat(pair1, pair2);
assertEquals(pair2, lessBeat);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
public class CreatedBeatTable extends ThrowableTester{
protected BeatTable beatTable;
protected List<Choice> list;

protected Pair pair;
protected Pair result;

protected Choice choice1;
protected Choice choice2;
protected Choice choice3;

protected Pair beats1;
protected Pair beats2;
protected Pair beats3;
protected Pair beats4;
protected Pair beats5;

@Before
public void setUp() {
beatTable = new BeatTable();
Expand All @@ -37,32 +37,33 @@ public void setUp() {
list.add(choice1);
list.add(choice2);
list.add(choice3);

beats1 = new Pair(150, 22);
beats2 = new Pair(100, 40);
beats3 = new Pair(150, 40);
beats4 = new Pair(100, 22);
beats5 = new Pair(150, 10);
}

protected void createNewBeatTableWithData() {
beatTable = new BeatTable(list);
beatTable.setElement(choice1, choice2, pair);
}
protected void createNewBeatTableWithComplexData() {

protected void createNewBeatTableWithComplexData() {
createNewBeatTableWithData();
beatTable.setElement(choice1, choice2, new Pair(14, 1));
beatTable.setElement(choice1, choice3, new Pair(13, 2));
beatTable.setElement(choice2, choice1, new Pair(12, 3));
beatTable.setElement(choice1, choice2, new Pair(5, 1));
beatTable.setElement(choice1, choice3, new Pair(4, 2));
beatTable.setElement(choice2, choice1, new Pair(1, 5));
beatTable.setElement(choice2, choice3, new Pair(11, 4));
beatTable.setElement(choice1, choice2, pair);
beatTable.setElement(choice3, choice1, new Pair(2, 4));
beatTable.setElement(choice3, choice2, new Pair(4, 11));
}

protected void setGetElementAsResult(final Choice first, final Choice second) {
result = beatTable.getElement(first, second);
result = beatTable.getElement(first, second);
}

protected void setCompareBeatsAsResult(final Pair first, final Pair second) {
result = beatTable.compareBeats(first, second);
}
Expand Down

0 comments on commit 1f2b864

Please sign in to comment.