feat: Implemented O(n) => O(log2(n)) speedup.
This commit is contained in:
parent
74d1f2be23
commit
54111831ca
|
@ -7,23 +7,44 @@ let avg = arr => arr.reduce((a, b) => (a + b), 0) / arr.length
|
||||||
|
|
||||||
/* Main function */
|
/* Main function */
|
||||||
|
|
||||||
function findPathsInner({ sourceElementId, targetElementId, pathSoFar, links, nodes, maxLengthOfPath }) {
|
function findPathsInner({
|
||||||
|
sourceElementId, sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
links, nodes,
|
||||||
|
maxLengthOfPath, pathSoFar
|
||||||
|
}) {
|
||||||
let paths = []
|
let paths = []
|
||||||
|
|
||||||
|
let minPos = Math.min(sourceElementPosition, targetElementPosition)
|
||||||
|
let maxPos = Math.max(sourceElementPosition, targetElementPosition)
|
||||||
|
let linksInner = links.filter(link =>
|
||||||
|
(minPos <= link.sourceElementPosition && link.sourceElementPosition <= maxPos) &&
|
||||||
|
(minPos <= link.targetElementPosition && link.targetElementPosition <= maxPos)
|
||||||
|
)
|
||||||
|
let linksNow = linksInner.filter(link => (link.source == sourceElementId || link.target == sourceElementId))
|
||||||
if (maxLengthOfPath > 0) {
|
if (maxLengthOfPath > 0) {
|
||||||
for (let link of links) {
|
for (let link of linksNow) {
|
||||||
if (
|
if (
|
||||||
((link.source == sourceElementId) && (link.target == targetElementId)) ||
|
((link.source == sourceElementId) && (link.target == targetElementId)) ||
|
||||||
((link.source == targetElementId) && (link.target == sourceElementId))
|
((link.source == targetElementId) && (link.target == sourceElementId))
|
||||||
) {
|
) {
|
||||||
paths.push(pathSoFar.concat(link).flat())
|
paths.push(pathSoFar.concat(link).flat())
|
||||||
} else if ((link.source == sourceElementId)) {
|
} else if ((link.source == sourceElementId)) {
|
||||||
let newPaths = findPathsInner({ sourceElementId: link.target, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath - 1) })
|
let newPaths = findPathsInner({
|
||||||
|
sourceElementId: link.target, sourceElementPosition: link.sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
pathSoFar: pathSoFar.concat(link).flat(),
|
||||||
|
links: linksInner, nodes, maxLengthOfPath: (maxLengthOfPath - 1)
|
||||||
|
})
|
||||||
if (newPaths.length != 0) {
|
if (newPaths.length != 0) {
|
||||||
paths.push(...newPaths)
|
paths.push(...newPaths)
|
||||||
}
|
}
|
||||||
} else if ((link.target == sourceElementId)) {
|
} else if ((link.target == sourceElementId)) {
|
||||||
let newPaths = findPathsInner({ sourceElementId: link.source, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath - 1) })
|
let newPaths = findPathsInner({
|
||||||
|
sourceElementId: link.source, sourceElementPosition: link.sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
pathSoFar: pathSoFar.concat(link).flat(),
|
||||||
|
links: linksInner, nodes, maxLengthOfPath: (maxLengthOfPath - 1) })
|
||||||
if (newPaths.length != 0) {
|
if (newPaths.length != 0) {
|
||||||
paths.push(...newPaths)
|
paths.push(...newPaths)
|
||||||
}
|
}
|
||||||
|
@ -33,17 +54,36 @@ function findPathsInner({ sourceElementId, targetElementId, pathSoFar, links, no
|
||||||
|
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
function findPaths({ sourceElementId, targetElementId, links, nodes }) {
|
function findPaths({
|
||||||
|
sourceElementId, sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
nodes, links, direction
|
||||||
|
}) {
|
||||||
let positionSourceElement = nodes.map((element, i) => (element.id)).indexOf(sourceElementId)
|
let positionSourceElement = nodes.map((element, i) => (element.id)).indexOf(sourceElementId)
|
||||||
let positionTargetElement = nodes.map((element, i) => (element.id)).indexOf(targetElementId)
|
let positionTargetElement = nodes.map((element, i) => (element.id)).indexOf(targetElementId)
|
||||||
let maxLengthOfPath = Math.abs(positionSourceElement - positionTargetElement)
|
let maxLengthOfPath = Math.abs(positionSourceElement - positionTargetElement)
|
||||||
|
return findPathsInner({
|
||||||
return findPathsInner({ sourceElementId, targetElementId, pathSoFar: [], links, nodes, maxLengthOfPath })
|
sourceElementId, sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
links, nodes, direction,
|
||||||
|
maxLengthOfPath, pathSoFar: []
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
function findDistance({ sourceElementId, sourceElementPosition, targetElementId, targetElementPosition, nodes, links, direction }) {
|
function findDistance({
|
||||||
let paths = findPaths({ sourceElementId, targetElementId, nodes, links })
|
sourceElementId, sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
nodes, links, direction
|
||||||
|
}) {
|
||||||
|
let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition)
|
||||||
|
let paths = findPathsInner({
|
||||||
|
sourceElementId, sourceElementPosition,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
links, nodes, direction,
|
||||||
|
maxLengthOfPath, pathSoFar: []
|
||||||
|
});
|
||||||
console.log(`findDistance from ${sourceElementPosition} to ${targetElementPosition}`)
|
console.log(`findDistance from ${sourceElementPosition} to ${targetElementPosition}`)
|
||||||
console.log(targetElementId)
|
console.log(targetElementId)
|
||||||
console.log(direction)
|
console.log(direction)
|
||||||
|
@ -106,7 +146,6 @@ function findDistancesForAllElements({ nodes, links }) {
|
||||||
let midpoint = Math.round(nodes.length / 2)
|
let midpoint = Math.round(nodes.length / 2)
|
||||||
let referenceElement = referenceElements.length > 0 ? referenceElements[0] : nodes[midpoint]
|
let referenceElement = referenceElements.length > 0 ? referenceElements[0] : nodes[midpoint]
|
||||||
// console.log(nodes)
|
// console.log(nodes)
|
||||||
let [upwardsLinks, downwardsLinks] = getDirectionalLinks({ nodes, links })
|
|
||||||
console.log(`referenceElement.position: ${referenceElement.position}`)
|
console.log(`referenceElement.position: ${referenceElement.position}`)
|
||||||
let distances = nodes.map(node => {
|
let distances = nodes.map(node => {
|
||||||
if (node.isReferenceValue || (node.id == referenceElement.id)) {
|
if (node.isReferenceValue || (node.id == referenceElement.id)) {
|
||||||
|
@ -114,14 +153,14 @@ function findDistancesForAllElements({ nodes, links }) {
|
||||||
} else {
|
} else {
|
||||||
console.log("node")
|
console.log("node")
|
||||||
console.log(node)
|
console.log(node)
|
||||||
let isUpwardsDirection = referenceElement.position < node.position;
|
let isUpwardsDirection = referenceElement.position < node.position
|
||||||
let distance = findDistance({
|
let distance = findDistance({
|
||||||
sourceElementId: referenceElement.id,
|
sourceElementId: referenceElement.id,
|
||||||
sourceElementPosition: referenceElement.position,
|
sourceElementPosition: referenceElement.position,
|
||||||
targetElementId: node.id,
|
targetElementId: node.id,
|
||||||
targetElementPosition: node.position,
|
targetElementPosition: node.position,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
links: links, // isUpwardsDirection ? upwardsLinks : downwardsLinks, // links
|
links: links,
|
||||||
direction: isUpwardsDirection ? "upwards" : "downwards"
|
direction: isUpwardsDirection ? "upwards" : "downwards"
|
||||||
})
|
})
|
||||||
return distance
|
return distance
|
||||||
|
@ -149,7 +188,19 @@ export function CreateTableWithDistances({ isListOrdered, orderedList, listOfEle
|
||||||
if (!isListOrdered || orderedList.length < listOfElements.length) {
|
if (!isListOrdered || orderedList.length < listOfElements.length) {
|
||||||
return (<div>{""}</div>)
|
return (<div>{""}</div>)
|
||||||
} else {
|
} else {
|
||||||
let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos }))
|
let nodes = []
|
||||||
|
let positionDictionary=({})
|
||||||
|
orderedList.forEach((id, pos) => {
|
||||||
|
nodes.push({ ...listOfElements[id], position: pos })
|
||||||
|
positionDictionary[id] = pos
|
||||||
|
})
|
||||||
|
// let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos }))
|
||||||
|
/* Pre-process links to talk in terms of distances */
|
||||||
|
links = links.map(link => ({...link,
|
||||||
|
sourceElementPosition: positionDictionary[link.source],
|
||||||
|
targetElementPosition: positionDictionary[link.target]
|
||||||
|
}))
|
||||||
|
/* Continue */
|
||||||
let distances = findDistancesForAllElements({ nodes, links })
|
let distances = findDistancesForAllElements({ nodes, links })
|
||||||
let rows = nodes.map((element, i) => ({ id: numToAlphabeticalString(element.position), position: element.position, name: element.name, distances: distances[i] }))
|
let rows = nodes.map((element, i) => ({ id: numToAlphabeticalString(element.position), position: element.position, name: element.name, distances: distances[i] }))
|
||||||
console.log("rows@CreateTableWithDistances")
|
console.log("rows@CreateTableWithDistances")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user