将完整的整数排列的ArrayLists排序为决策树结构

时间:2015-09-03 13:26:17

标签: java algorithm arraylist tree permutation

背景:我有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]

以便按预期访问我的树节点: enter image description here

那么我怎样才能递归地将Lists递归到该结构中呢?

2 个答案:

答案 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;
        }
    }
}