1 package net.bmahe.genetics4j.neat.spec;
2
3 import java.util.HashSet;
4 import java.util.List;
5 import java.util.Objects;
6
7 import org.apache.commons.lang3.Validate;
8
9 class NeatNodeLayoutValidation {
10
11 private NeatNodeLayoutValidation() {
12 }
13
14 static void validate(final List<Integer> inputNodeIds, final List<Integer> outputNodeIds,
15 final long hiddenNodeIdStartInclusive, final long hiddenNodeIdEndExclusive) {
16 Objects.requireNonNull(inputNodeIds);
17 Objects.requireNonNull(outputNodeIds);
18 Validate.isTrue(inputNodeIds.isEmpty() == false, "At least one input node is required");
19 Validate.isTrue(outputNodeIds.isEmpty() == false, "At least one output node is required");
20 Validate.isTrue(hiddenNodeIdStartInclusive >= 0, "Hidden-node range start must be non-negative");
21 Validate.isTrue(hiddenNodeIdStartInclusive < hiddenNodeIdEndExclusive, "Hidden-node range must not be empty");
22 Validate.isTrue(
23 hiddenNodeIdEndExclusive <= NeatNodeLayout.MAX_NODE_ID_EXCLUSIVE,
24 "Hidden-node range exceeds the non-negative int domain");
25
26 final var inputIds = new HashSet<Integer>();
27 for (final Integer nodeId : inputNodeIds) {
28 validateExternalId(nodeId, hiddenNodeIdStartInclusive, hiddenNodeIdEndExclusive);
29 Validate.isTrue(inputIds.add(nodeId), "Duplicate input node ID: %d", nodeId);
30 }
31
32 final var outputIds = new HashSet<Integer>();
33 for (final Integer nodeId : outputNodeIds) {
34 validateExternalId(nodeId, hiddenNodeIdStartInclusive, hiddenNodeIdEndExclusive);
35 Validate.isTrue(outputIds.add(nodeId), "Duplicate output node ID: %d", nodeId);
36 Validate.isTrue(inputIds.contains(nodeId) == false, "Node ID is both an input and output: %d", nodeId);
37 }
38 }
39
40 private static void validateExternalId(final Integer nodeId, final long hiddenNodeIdStartInclusive,
41 final long hiddenNodeIdEndExclusive) {
42 Objects.requireNonNull(nodeId);
43 Validate.isTrue(nodeId >= 0, "External node ID must be non-negative: %d", nodeId);
44 Validate.isTrue(
45 nodeId < hiddenNodeIdStartInclusive || nodeId >= hiddenNodeIdEndExclusive,
46 "External node ID %d conflicts with the hidden-node range",
47 nodeId);
48 }
49 }