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