我有一些复杂的计算算法,基本上可以测试一些较小的矩阵是否适合另一个大矩阵。
如果所有小矩阵都适合大矩阵,则取决于较小矩阵的顺序。如果小矩阵不适合,它应该重新排列 ArrayList 并重试,直到测试所有可能的顺序/序列。
如果我有 5 个小矩阵,那么总共有5 个!(= 120)数组可以有的可能顺序。
我的问题是我不知道如何重新排列这些对象(矩阵),所以我可以测试每个可能的顺序。我希望有人可以帮助我吗?
对于n
对象有n!
排列。考虑一个集合:
S = {a1, a2, a3 ..., an};
找到上述集合的排列的算法可能是:
foreach(item i : S) {
/* all other item except i1 and i */
foreach(item i1 : S - {i}) {
foreach(item i2 : S - {i, i1}) {
.
.
.
foreach(item in : S - {i, i2, .... in-1}) {
/* permutation list */
P = { i1, i2, ...., in-1, in };
}
}
}
}
显然我们不能有n
for
循环,但我们可以递归地构造这个算法,直到我们得到n
list 中的元素P
。下面是使用上述算法进行排列的实际 java 代码:
public static void
permutations(Set<Integer> items, Stack<Integer> permutation, int size) {
/* permutation stack has become equal to size that we require */
if(permutation.size() == size) {
/* print the permutation */
System.out.println(Arrays.toString(permutation.toArray(new Integer[0])));
}
/* items available for permutation */
Integer[] availableItems = items.toArray(new Integer[0]);
for(Integer i : availableItems) {
/* add current item */
permutation.push(i);
/* remove item from available item set */
items.remove(i);
/* pass it on for next permutation */
permutations(items, permutation, size);
/* pop and put the removed item back */
items.add(permutation.pop());
}
}
下面是主要方法:
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<Integer> s = new HashSet<Integer>();
s.add(1);
s.add(2);
s.add(3);
permutations(s, new Stack<Integer>(), s.size());
}
它打印了结果:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
如果您使用的是 Java > 8,则有一个更智能的解决方案:
static Stream<List<Integer>> permutations(List<Integer> input) {
if (input.size() == 1) {
return Stream.of(new LinkedList<>(input));
}
return input.stream()
.flatMap(first -> permutations(input.stream()
.filter(a -> !a.equals(first))
.toList())
.map(LinkedList::new)
.peek(l -> l.addFirst(first)));
}