背景:我有ArrayList<Integer>
。 Integer
是某些订单对象的引用ID。稍后,这个列表将告诉分支定界算法,该算法首先计划进入计划,其中第二个等。
B&amp; B是我想用作深度优先搜索的基于树的算法。
所以,我需要列表的每个排列。我的第一次尝试使用了递归:
private List<List<Integer>> permutations(List<Integer> input) {
List<List<Integer>> permutations = new ArrayList<List<Integer>>();
if (input.size() == 0) {
permutations.add(new ArrayList<Integer>());
return permutations;
}
Integer firstElement = input.remove(0);
List<List<Integer>> recursiveReturn = permutations(input);
for (List<Integer> li : recursiveReturn) {
for (int index = 0; index <= li.size(); index++) {
List<Integer> temp = new ArrayList<Integer>(li);
temp.add(index, firstElement);
permutations.add(temp);
}
}
return permutations;
}
并获得3个订单的输出:
[1, 2, 3]
[2, 1, 3]
[2, 3, 1]
[1, 3, 2]
[3, 1, 2]
[3, 2, 1]
但是在深度优先搜索的情况下,我需要:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
那么我怎样才能递归地将Lists
递归到该结构中呢?
答案 0 :(得分:2)
我设法提出了一种算法,该算法以正确的顺序从原始输入列表中获取排列。它不依赖于订购的列表内容。
private List<List<Integer>> permutations(List<Integer> input)
{
List<List<Integer>> permutations = new ArrayList<>();
// if input's size is one, then there is only one permutation to return
// wrap it as single entry inside permutations and return
if (input.size() == 1) {
permutations.add(input);
return permutations;
}
// if input's size is more than one, then we need to calc permutations
// we iterate over the input, each time taking out one cell
// the remaining cells become tree "under" this cell
for (int i = 0; i < input.size(); i++) {
List<Integer> remainingCells = new ArrayList<>(input);
Integer firstElement = remainingCells.remove(i);
List<List<Integer>> permutationsUnderFirstElement = permutations(remainingCells);
for (List<Integer> permutation : permutationsUnderFirstElement) {
permutation.add(0, firstElement);
permutations.add(permutation);
}
}
return permutations;
}
答案 1 :(得分:1)
如何对现有的排列进行排序:
final List<List<Integer>> permutations = new ArrayList<>();
permutations.add(Arrays.asList(1, 2, 3));
permutations.add(Arrays.asList(1, 3, 2));
permutations.add(Arrays.asList(2, 1, 3));
permutations.add(Arrays.asList(2, 3, 1));
permutations.add(Arrays.asList(3, 1, 2));
permutations.add(Arrays.asList(3, 2, 1));
System.out.println("initial state=" + permutations);
Collections.reverse(permutations);
System.out.println("after shuffle=" + permutations);
final List<List<Integer>> result = permutations.stream().sorted((o1, o2) -> {
final int length = o1.size();
int diff = 0;
for (int i = 0; i < length; ++i) {
diff = o1.get(i) - o2.get(i);
if (diff != 0) {
break;
}
}
return diff;
}).collect(Collectors.toList());
System.out.println("sorted again =" + result);
如何生成排序排列(gist):
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* @author Karol Krol
*/
public class Permutation {
private Permutation() {
}
public static List<List<Integer>> permutation(final int[] numbers) {
final PermutationCollector permutationCollector = new PermutationCollector();
permutation(new int[0], numbers, permutationCollector);
return permutationCollector.getResult();
}
private static void permutation(int[] prefix, int[] array, final Consumer<int[]> operation) {
int length = array.length;
if (length == 0) {
operation.accept(prefix);
} else {
for (int i = 0; i < length; ++i) {
final int[] newPrefix = append(prefix, array[i]);
final int[] reducedArray = reduce(array, i);
permutation(newPrefix, reducedArray, operation);
}
}
}
private static int[] append(int[] array, int element) {
int newLength = array.length + 1;
array = Arrays.copyOf(array, newLength);
array[newLength - 1] = element;
return array;
}
private static int[] reduce(int[] array, int index) {
final int newLength = array.length - 1;
if (index == 0) {
return Arrays.copyOfRange(array, 1, array.length);
} else {
final int[] dest = new int[newLength];
System.arraycopy(array, 0, dest, 0, index);
System.arraycopy(array, index + 1, dest, index, newLength - index);
return dest;
}
}
public static class PermutationCollector implements Consumer<int[]> {
private List<List<Integer>> result = new ArrayList<>();
@Override
public void accept(int[] ints) {
result.add(IntStream.of(ints).boxed().collect(Collectors.toList()));
}
public List<List<Integer>> getResult() {
return result;
}
}
}