mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-21 22:31:44 +01:00
Test permutations level by level
This commit is contained in:
parent
61838920ed
commit
96575dcad7
2 changed files with 59 additions and 25 deletions
|
@ -21,8 +21,10 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
|
@ -65,7 +67,7 @@ public class PermutationUtil {
|
|||
list,
|
||||
new ArrayList<>(),
|
||||
predicate,
|
||||
maxIterations);
|
||||
new AtomicInteger(maxIterations));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,29 +75,49 @@ public class PermutationUtil {
|
|||
List<T> list,
|
||||
List<List<T>> lists,
|
||||
BiFunction<R, List<T>, Boolean> predicate,
|
||||
int maxIterations) {
|
||||
|
||||
if (maxIterations == 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
maxIterations--;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
List<T> newList = new ArrayList<>(list);
|
||||
newList.remove(i);
|
||||
|
||||
// We want to avoid testing duplicates
|
||||
if (!lists.contains(newList)) {
|
||||
if (predicate.apply(targetValue, newList)) {
|
||||
return newList;
|
||||
} else {
|
||||
lists.add(newList);
|
||||
}
|
||||
AtomicInteger maxIterations) {
|
||||
for (int level = 0; level < list.size(); level++) {
|
||||
// Test one level at a time
|
||||
var result = checkLevel(targetValue, list, predicate, level, 0, maxIterations);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
List<T> nextList = lists.remove(0);
|
||||
return findMatchingPermutation(targetValue, nextList, lists, predicate, maxIterations);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static <T, R> List<T> checkLevel(R targetValue,
|
||||
List<T> previousLevel,
|
||||
BiFunction<R, List<T>, Boolean> predicate,
|
||||
int level,
|
||||
int permutationIndex,
|
||||
AtomicInteger maxIterations) {
|
||||
if (previousLevel.size() == 1) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
for (int i = permutationIndex; i < previousLevel.size(); i++) {
|
||||
if (maxIterations.get() <= 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<T> newList = new ArrayList<>(previousLevel);
|
||||
newList.remove(i);
|
||||
if (level == 0) {
|
||||
maxIterations.decrementAndGet();
|
||||
// Check all permutations on this level
|
||||
if (predicate.apply(targetValue, newList)) {
|
||||
return newList;
|
||||
}
|
||||
} else {
|
||||
// Test next level
|
||||
var result = checkLevel(targetValue, newList, predicate, level - 1, i, maxIterations);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
//TODO optimize algorithm so that it starts from all objects and goes down instead starting with from the bottom.
|
||||
|
|
|
@ -23,13 +23,11 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@Slf4j
|
||||
public class PermutationTest {
|
||||
|
||||
|
||||
|
@ -109,13 +107,12 @@ public class PermutationTest {
|
|||
int limit = 1048575;
|
||||
List<String> result;
|
||||
List<String> list;
|
||||
String targetValue;
|
||||
List<String> expected;
|
||||
BiFunction<String, List<String>, Boolean> predicate = (target, variationList) -> variationList.toString().equals(target);
|
||||
|
||||
list = Arrays.asList(a, b, c, d, e);
|
||||
|
||||
expected = Arrays.asList("-");
|
||||
expected = Arrays.asList(a);
|
||||
result = PermutationUtil.findMatchingPermutation(expected.toString(), list, predicate, limit);
|
||||
assertTrue(expected.toString().equals(result.toString()));
|
||||
|
||||
|
@ -123,7 +120,22 @@ public class PermutationTest {
|
|||
expected = Arrays.asList(a, c, e);
|
||||
result = PermutationUtil.findMatchingPermutation(expected.toString(), list, predicate, limit);
|
||||
assertTrue(expected.toString().equals(result.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBreakAtLimit() {
|
||||
BiFunction<String, List<String>, Boolean> predicate =
|
||||
(target, variationList) -> variationList.toString().equals(target);
|
||||
var list = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o");
|
||||
var expected = Arrays.asList("b", "g", "m");
|
||||
|
||||
// Takes around 32508 tries starting from longer strings
|
||||
var limit = 100000;
|
||||
var result = PermutationUtil.findMatchingPermutation(expected.toString(), list, predicate, limit);
|
||||
assertTrue(expected.toString().equals(result.toString()));
|
||||
limit = 1000;
|
||||
result = PermutationUtil.findMatchingPermutation(expected.toString(), list, predicate, limit);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue