generated from michael/webpack-base
exclude both sources and sinks from findAcyclicInternalNewConns
This commit is contained in:
parent
a0a2e7c9bb
commit
a5884a68db
@ -229,7 +229,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { edgesToNodes, NodeID, traceParents, RawEdge, traceChildren } from './network';
|
import { edgesToNodes, NodeID, traceParents, RawEdge, traceChildren } from './network';
|
||||||
import { keyMax, mapInvert, mapMap, randchoice, randint, randomNegPos, setDifference, setMap } from './util';
|
import { keyMax, mapInvert, mapMap, randchoice, randint, randomNegPos, setDifference, setMap, setUnion } from './util';
|
||||||
|
|
||||||
export interface GeneData {
|
export interface GeneData {
|
||||||
innovation: number;
|
innovation: number;
|
||||||
@ -548,19 +548,18 @@ export function findAcyclicInternalNewConns<DataT>(rawEdges: RawEdge<DataT>[]):
|
|||||||
const parents = traceParents(nodes);
|
const parents = traceParents(nodes);
|
||||||
const children = traceChildren(nodes);
|
const children = traceChildren(nodes);
|
||||||
|
|
||||||
// TODO: exclude *both* sources and sinks
|
// exclude *both* sources and sinks
|
||||||
// - sources are defined during think
|
// - sources are defined during think, connections will be ignored
|
||||||
// - sinks should not be connected? <-- they probably could be, but not clean imo
|
// - sinks should not be connected? <-- they probably could be, but it would be unclean imo
|
||||||
const sources = new Set(Array.from(parents.entries()).flatMap(([k, v]) => (v.size === 0 ? [k] : [])));
|
const sources = new Set(Array.from(parents.entries()).flatMap(([k, v]) => (v.size === 0 ? [k] : [])));
|
||||||
const sinks = new Set(Array.from(children.entries()).flatMap(([k, v]) => (v.size === 0 ? [k] : [])));
|
const sinks = new Set(Array.from(children.entries()).flatMap(([k, v]) => (v.size === 0 ? [k] : [])));
|
||||||
|
|
||||||
const acyclic = new Map<NodeID, Set<NodeID>>();
|
const acyclic = new Map<NodeID, Set<NodeID>>();
|
||||||
for (const [nodeID, nodeParents] of parents.entries()) {
|
for (const [nodeID, nodeParents] of parents.entries()) {
|
||||||
const nodeParentIDs = setMap(nodeParents, n => n.id);
|
const nodeParentIDs = setMap(nodeParents, n => n.id);
|
||||||
const nodeIDsAcyclic = setDifference(allNodeIDs, nodeParentIDs);
|
const exclude = setUnion(nodeParentIDs, sources, sinks, new Set([nodeID]));
|
||||||
nodeIDsAcyclic.delete(nodeID);
|
const nodeIDsAcyclic = setDifference(allNodeIDs, exclude);
|
||||||
const nodeIDsAcyclicNonSource = setDifference(nodeIDsAcyclic, sources);
|
acyclic.set(nodeID, nodeIDsAcyclic);
|
||||||
acyclic.set(nodeID, nodeIDsAcyclicNonSource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// flatten
|
// flatten
|
||||||
|
@ -46,7 +46,7 @@ export function mapMap<K1, V1, K2, V2>(m: Map<K1, V1>, mapper: (k: K1, v: V1) =>
|
|||||||
return new Map(Array.from(m.entries()).map(([k, v]) => mapper(k, v)));
|
return new Map(Array.from(m.entries()).map(([k, v]) => mapper(k, v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setIntersection<T>(...sets: Set<T>[]) {
|
export function setIntersection<T>(...sets: Set<T>[]): Set<T> {
|
||||||
// a & b & ...
|
// a & b & ...
|
||||||
if (sets.length === 0) return new Set();
|
if (sets.length === 0) return new Set();
|
||||||
const intersection = new Set(sets[0]!);
|
const intersection = new Set(sets[0]!);
|
||||||
@ -56,7 +56,7 @@ export function setIntersection<T>(...sets: Set<T>[]) {
|
|||||||
return intersection;
|
return intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setUnion<T>(...sets: Set<T>[]) {
|
export function setUnion<T>(...sets: Set<T>[]): Set<T> {
|
||||||
// a & b & ...
|
// a & b & ...
|
||||||
if (sets.length === 0) return new Set();
|
if (sets.length === 0) return new Set();
|
||||||
const union = new Set(sets[0]!);
|
const union = new Set(sets[0]!);
|
||||||
|
@ -380,21 +380,21 @@ function testFindAcyclicInternalNewConns() {
|
|||||||
const options = findAcyclicInternalNewConns(edges);
|
const options = findAcyclicInternalNewConns(edges);
|
||||||
const expected = [
|
const expected = [
|
||||||
// not A -> B - B is a source
|
// not A -> B - B is a source
|
||||||
{ src_id: 'A', dst_id: 'F' },
|
// not A -> F - F is a sink
|
||||||
// not B -> A - A is a source
|
// not B -> A - A is a source
|
||||||
{ src_id: 'B', dst_id: 'C' },
|
{ src_id: 'B', dst_id: 'C' },
|
||||||
{ src_id: 'B', dst_id: 'E' },
|
// not B -> E - E is a sink
|
||||||
{ src_id: 'B', dst_id: 'F' },
|
// not B -> F - F is a sink
|
||||||
// not C -> B - B is a source
|
// not C -> B - B is a source
|
||||||
{ src_id: 'C', dst_id: 'D' },
|
{ src_id: 'C', dst_id: 'D' },
|
||||||
{ src_id: 'C', dst_id: 'F' },
|
// not C -> F - F is a sink
|
||||||
{ src_id: 'D', dst_id: 'C' },
|
{ src_id: 'D', dst_id: 'C' },
|
||||||
// not E -> B - B is a parent of E
|
// not E -> B - B is a parent of E
|
||||||
{ src_id: 'E', dst_id: 'F' },
|
// not E -> F - F is a sink
|
||||||
// not F -> A - A is a parent of F
|
// not F -> A - A is a parent of F
|
||||||
// not F -> B - B is a parent of F
|
// not F -> B - B is a parent of F
|
||||||
{ src_id: 'F', dst_id: 'C' },
|
{ src_id: 'F', dst_id: 'C' },
|
||||||
{ src_id: 'F', dst_id: 'E' },
|
// not F -> E - E is a sink
|
||||||
];
|
];
|
||||||
|
|
||||||
function strcmp(a: string, b: string) {
|
function strcmp(a: string, b: string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user