com.happy3w.math.graph.ScIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of math Show documentation
Show all versions of math Show documentation
Some kits for common use
package com.happy3w.math.graph;
import com.happy3w.java.ext.NeedFindIterator;
import com.happy3w.java.ext.NullableOptional;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Stack;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ScIterator extends NeedFindIterator> {
private final Map> nodesToDeal;
private Stack> candidateCircles = new Stack<>();
private Stack idPath = new Stack<>();
public ScIterator(Map> nodes) {
this.nodesToDeal = new HashMap<>(nodes);
}
@Override
protected NullableOptional> findNext() {
ScNode leafNode = findLeafNode();
if (leafNode == null) {
return NullableOptional.empty();
} else {
leafNode.idStream()
.forEach(nodesToDeal::remove);
return NullableOptional.of(leafNode);
}
}
private ScNode findLeafNode() {
while (!nodesToDeal.isEmpty()) {
SingleScNode curScNode;
if (!idPath.isEmpty()) {
NK lastId = idPath.pop();
GraphNode graphNode = nodesToDeal.get(lastId);
curScNode = SingleScNode.from(graphNode);
} else if (!candidateCircles.isEmpty()) {
CircleInfo curCircle = candidateCircles.pop();
NK newStartNode = curCircle.nextNewStartNode();
if (newStartNode == null) {
idPath.addAll(curCircle.getPathFromParent());
return new CombineScNode(idToNode(curCircle.getCircle(), nodesToDeal::get));
}
candidateCircles.push(curCircle);
GraphNode graphNode = nodesToDeal.get(newStartNode);
if (graphNode == null) {
continue;
}
curScNode = SingleScNode.from(graphNode);
} else {
GraphNode graphNode = nodesToDeal.values().iterator().next();
curScNode = SingleScNode.from(graphNode);
}
NK curId = curScNode.getGraphNode().getId();
CircleInfo curCircle = CircleInfo.createNewCircle(idPath, curId, nodesToDeal::get);
if (curCircle != null) {
idPath.clear();
candidateCircles.push(curCircle);
} else if (CircleInfo.mergeIntoBigCircle(idPath, curId, candidateCircles, nodesToDeal::get)) {
idPath.clear();
} else {
SingleScNode outNode = pickAnyOutNode(curScNode.getGraphNode(), nodesToDeal::get);
if (outNode == null) {
return curScNode;
}
idPath.push(curId);
idPath.push(outNode.getGraphNode().getId());
}
}
return null;
}
private SingleScNode pickAnyOutNode(GraphNode node,
Function> nodeMapper) {
return node.outcomeStream()
.map(edge -> nodeMapper.apply(edge.getTo()))
.filter(Objects::nonNull)
.map(SingleScNode::from)
.findFirst()
.orElse(null);
}
private List> idToNode(Collection ids,
Function> idNodeTranslator) {
return ids.stream()
.map(idNodeTranslator)
.collect(Collectors.toList());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy