Random with SEEED
This commit is contained in:
@@ -18,29 +18,9 @@ export const ProducingGraph = <T extends Dict<unknown>,>({nodes, inputs, outputs
|
|||||||
const [[rows, nodeMap], setGraph] = useState<[string[][], Dict<GraphNodeWithIds<T|AdditionalNode>>]>([[], {}])
|
const [[rows, nodeMap], setGraph] = useState<[string[][], Dict<GraphNodeWithIds<T|AdditionalNode>>]>([[], {}])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setGraph(graphUntangled(nodes, inputs, outputs ?? []))
|
setGraph(graphUntangled(nodes, inputs, outputs ?? []))
|
||||||
setTimeout(() => setGraph(graphUntangled(nodes, inputs, outputs ?? [], 5000)), 0)
|
setTimeout(() => setGraph(graphUntangled(nodes, inputs, outputs ?? [], 3000)), 0)
|
||||||
}, [inputs, nodes, outputs])
|
}, [inputs, nodes, outputs])
|
||||||
|
|
||||||
/*const rowsWithInOut: (GraphNode<T>|AdditionalNode)[][] = useMemo(() => {
|
|
||||||
const addedInputs = new Set<string>()
|
|
||||||
const res: (GraphNode<T>|AdditionalNode)[][] = deepcopy([[], ...rows, []])
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
const rowOutputs = uniquify(rows[i].flatMap(row => row.outputs))
|
|
||||||
for (let rowOutput of rowOutputs) {
|
|
||||||
outputs?.includes(rowOutput) && res[i+2].push({___type: 'o', value: rowOutput})
|
|
||||||
}
|
|
||||||
const rowInputs = uniquify(rows[i].flatMap(row => row.inputs))
|
|
||||||
for (let rowInput of rowInputs) {
|
|
||||||
if (addedInputs.has(rowInput))
|
|
||||||
!res[i].some(node => isAdditionalNode(node) && node.value === rowInput) && res[i].push({___type: 'h', value: rowInput})
|
|
||||||
else if (inputs.includes(rowInput))
|
|
||||||
res[i].push({___type: 'i', value: rowInput})
|
|
||||||
addedInputs.add(rowInput)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}, [rows, inputs, outputs])*/
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!planeRef.current) return
|
if (!planeRef.current) return
|
||||||
const plane = planeRef.current
|
const plane = planeRef.current
|
||||||
@@ -61,22 +41,22 @@ export const ProducingGraph = <T extends Dict<unknown>,>({nodes, inputs, outputs
|
|||||||
svg.setAttributeNS(null, 'viewBox', `0 0 ${width} ${height}`)
|
svg.setAttributeNS(null, 'viewBox', `0 0 ${width} ${height}`)
|
||||||
svg.replaceChildren()
|
svg.replaceChildren()
|
||||||
|
|
||||||
|
let paths: string[] = []
|
||||||
plane.querySelectorAll('[data-outputs]').forEach(startNode => {
|
plane.querySelectorAll('[data-outputs]').forEach(startNode => {
|
||||||
if (!(startNode instanceof HTMLElement)) return
|
if (!(startNode instanceof HTMLElement)) return
|
||||||
(startNode.dataset.outputs?.split(' ') ?? []).forEach(output => {
|
(startNode.dataset.outputs?.split(' ') ?? []).forEach(output => {
|
||||||
const endNode = plane.querySelector(`[data-name="${output}"]`)
|
const endNode = plane.querySelector(`[data-name="${output}"]`)
|
||||||
if (!(endNode instanceof HTMLElement)) return
|
if (!(endNode instanceof HTMLElement)) return
|
||||||
const path = document.createElementNS('http://www.w3.org/2000/svg',"path")
|
paths.push(createPath(plane.getBoundingClientRect(), startNode.getBoundingClientRect(), endNode.getBoundingClientRect()))
|
||||||
path.setAttributeNS(null, 'd', createPath(plane.getBoundingClientRect(), startNode.getBoundingClientRect(), endNode.getBoundingClientRect()))
|
|
||||||
svg.appendChild(path)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
plane.querySelectorAll('[data-hidden][data-outputs]').forEach(elem => {
|
plane.querySelectorAll('[data-hidden="true"][data-outputs]').forEach(elem => {
|
||||||
if (!(elem instanceof HTMLElement)) return
|
if (!(elem instanceof HTMLElement)) return
|
||||||
const path = document.createElementNS('http://www.w3.org/2000/svg',"path")
|
paths.push(drawLine(plane.getBoundingClientRect(), elem.getBoundingClientRect()))
|
||||||
path.setAttributeNS(null, 'd', drawLine(plane.getBoundingClientRect(), elem.getBoundingClientRect()))
|
|
||||||
svg.appendChild(path)
|
|
||||||
})
|
})
|
||||||
|
const path = document.createElementNS('http://www.w3.org/2000/svg',"path")
|
||||||
|
path.setAttributeNS(null, 'd', paths.join(' '))
|
||||||
|
svg.appendChild(path)
|
||||||
})
|
})
|
||||||
|
|
||||||
return <div className={styles.plane} ref={planeRef}>
|
return <div className={styles.plane} ref={planeRef}>
|
||||||
@@ -87,14 +67,17 @@ export const ProducingGraph = <T extends Dict<unknown>,>({nodes, inputs, outputs
|
|||||||
const node = nodeMap[uid]
|
const node = nodeMap[uid]
|
||||||
return (
|
return (
|
||||||
!isAdditionalNode(node)
|
!isAdditionalNode(node)
|
||||||
? <ChildType
|
? <span
|
||||||
data-name={node.___uid}
|
data-name={node.___uid}
|
||||||
data-inputs={node.___uidInputs.join(' ')}
|
data-inputs={node.___uidInputs.join(' ')}
|
||||||
data-outputs={node.___uidOutputs.join(' ')}
|
data-outputs={node.___uidOutputs.join(' ')}
|
||||||
className={styles.node}
|
key={node.___uid}
|
||||||
key={node.name}
|
data-hidden={node.___uidOutputs.length > 0}>
|
||||||
node={node}
|
<ChildType
|
||||||
/>
|
className={styles.node}
|
||||||
|
node={node}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
: node.___type === 'h'
|
: node.___type === 'h'
|
||||||
? <span
|
? <span
|
||||||
className={styles.hidden}
|
className={styles.hidden}
|
||||||
@@ -105,7 +88,6 @@ export const ProducingGraph = <T extends Dict<unknown>,>({nodes, inputs, outputs
|
|||||||
data-hidden={true}></span>
|
data-hidden={true}></span>
|
||||||
: node.___type === 'i'
|
: node.___type === 'i'
|
||||||
? <span
|
? <span
|
||||||
className={styles.input}
|
|
||||||
key={node.___uid}
|
key={node.___uid}
|
||||||
data-name={node.___uid}
|
data-name={node.___uid}
|
||||||
data-outputs={node.___uidOutputs.join(' ')}
|
data-outputs={node.___uidOutputs.join(' ')}
|
||||||
@@ -113,7 +95,6 @@ export const ProducingGraph = <T extends Dict<unknown>,>({nodes, inputs, outputs
|
|||||||
<EntityIcon value={node.name}/>
|
<EntityIcon value={node.name}/>
|
||||||
</span>
|
</span>
|
||||||
: <EntityIcon
|
: <EntityIcon
|
||||||
className={styles.input}
|
|
||||||
key={node.___uid}
|
key={node.___uid}
|
||||||
value={node.name}
|
value={node.name}
|
||||||
data-name={node.___uid}
|
data-name={node.___uid}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {AdditionalNode, GraphNode, GraphNodeWithIds, isAdditionalNode} from "./t
|
|||||||
import {Dict} from "../types";
|
import {Dict} from "../types";
|
||||||
import deepcopy from "deepcopy";
|
import deepcopy from "deepcopy";
|
||||||
import {isNonNullable, shuffleInplace, sortByProperty, uniquify} from "../utils";
|
import {isNonNullable, shuffleInplace, sortByProperty, uniquify} from "../utils";
|
||||||
|
import seedrandom from "seedrandom";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -212,6 +213,7 @@ export function findBest<T extends Dict<unknown>>(rowsWithInOut: string[][], nod
|
|||||||
let bestRows = deepcopy(rowsWithInOut)
|
let bestRows = deepcopy(rowsWithInOut)
|
||||||
let limit = Date.now() + timeLimit
|
let limit = Date.now() + timeLimit
|
||||||
let iterSinceImprovements = 0
|
let iterSinceImprovements = 0
|
||||||
|
let rng = seedrandom.alea("We are SEEED, ya!")
|
||||||
while (true) {
|
while (true) {
|
||||||
if (Date.now() > limit) break
|
if (Date.now() > limit) break
|
||||||
if (iterSinceImprovements > 100) break
|
if (iterSinceImprovements > 100) break
|
||||||
@@ -223,7 +225,7 @@ export function findBest<T extends Dict<unknown>>(rowsWithInOut: string[][], nod
|
|||||||
} else {
|
} else {
|
||||||
iterSinceImprovements++
|
iterSinceImprovements++
|
||||||
}
|
}
|
||||||
rowsOptimized.forEach(shuffleInplace)
|
rowsOptimized.forEach((row, ) => shuffleInplace(row, rng))
|
||||||
}
|
}
|
||||||
console.log(bestScore)
|
console.log(bestScore)
|
||||||
return bestRows
|
return bestRows
|
||||||
@@ -244,9 +246,5 @@ export function graphUntangled<T extends Dict<unknown>>(nodes: GraphNode<T>[], i
|
|||||||
//console.table(rowsWithInOut)
|
//console.table(rowsWithInOut)
|
||||||
//console.table(nodesLinked)
|
//console.table(nodesLinked)
|
||||||
const bestRows = findBest(rowsWithInOut, nodesWithInOut, timeLimit)
|
const bestRows = findBest(rowsWithInOut, nodesWithInOut, timeLimit)
|
||||||
const orderRow = bestRows.find(row => row.length > 1)
|
|
||||||
if ((orderRow?.[0]?.localeCompare(orderRow[orderRow.length-1]) ?? 0) > 0) {
|
|
||||||
bestRows.forEach(row => row.reverse())
|
|
||||||
}
|
|
||||||
return [bestRows, nodesLinked]
|
return [bestRows, nodesLinked]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {Dict} from "./types";
|
import {Dict} from "./types";
|
||||||
|
import {PRNG} from "seedrandom";
|
||||||
|
|
||||||
export function isNonNullable<T>(any: T): any is NonNullable<T> {
|
export function isNonNullable<T>(any: T): any is NonNullable<T> {
|
||||||
return any !== undefined && any !== null
|
return any !== undefined && any !== null
|
||||||
@@ -26,9 +27,9 @@ export function uniquify<T>(array: T[]): T[] {
|
|||||||
return Array.from(new Set(array))
|
return Array.from(new Set(array))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shuffleInplace<T>(array: T[]): T[] {
|
export function shuffleInplace<T>(array: T[], rng: PRNG): T[] {
|
||||||
for (let i = array.length - 1; i > 0; i--) {
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
const j = Math.floor(rng.quick() * (i + 1));
|
||||||
[array[i], array[j]] = [array[j], array[i]];
|
[array[i], array[j]] = [array[j], array[i]];
|
||||||
}
|
}
|
||||||
return array
|
return array
|
||||||
|
|||||||
Reference in New Issue
Block a user