aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/main/java/tools/refinery/store/statecoding/stateequivalence/CombinationNodePairingPermutations.java
blob: eacd3a2a72ec49b3c5caf91b987ab1b3845f0ad1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package tools.refinery.store.statecoding.stateequivalence;

import java.util.ArrayList;
import java.util.List;

class CombinationNodePairingPermutations {
	private final List<List<int[]>> permutations = new ArrayList<>();

	public CombinationNodePairingPermutations(int max) {
		initializePermutations(max);
	}

	public List<int[]> getPermutations(int max) {
		if (max >= permutations.size()) {
			throw new IllegalArgumentException("Only permutations up to %d elements are supported".formatted(max));
		}
		return permutations.get(max);
	}

	/**
	 * Generates and stores permutations up to a given size. If the number would be more than a limit, it provides a
	 * single permutation only.
	 *
	 * @param max The max number in the permutation
	 * @return A complete list of permutations of numbers 0...max, or a single permutation.
	 */
	private List<int[]> initializePermutations(int max) {
		if (max < permutations.size()) {
			return permutations.get(max);
		}
		if (max == 0) {
			List<int[]> result = new ArrayList<>();
			result.add(new int[1]);
			permutations.add(result);
			return result;
		}
		List<int[]> result = new ArrayList<>();
		List<int[]> previousPermutations = initializePermutations(max - 1);
		for (var permutation : previousPermutations) {
			for (int pos = 0; pos <= max; pos++) {
				int[] newPermutation = new int[max + 1];
				System.arraycopy(permutation, 0, newPermutation, 0, pos);
				newPermutation[pos] = max;
				if (max - (pos + 1) >= 0)
					System.arraycopy(permutation, pos + 1, newPermutation, pos + 1 + 1, max - (pos + 1));
				result.add(newPermutation);
			}
		}
		permutations.add(result);
		return result;
	}
}