Advertisement
Guest User

Untitled

a guest
Feb 24th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.19 KB | None | 0 0
  1. 'use strict';
  2.  
  3. // Copyright 2016 Fetch Robotics, Inc.
  4. // Author(s): Andrey Filenko
  5.  
  6. /**
  7. * findSubGraphs() searches for sub-graphs for a given lane.
  8. *
  9. * @param {Object} node - currently checked node. If current sub-graph does not contain this node yet,
  10. * it's added to sub-graph nodes, and algorithm checks all nodes connected to the checked one.
  11. *
  12. * @param {Object} lane - contains nodes and edges arrays.
  13. *
  14. * @param {Object} recursion - stores results and params needed to exit from recursion.
  15. *
  16. * @return {Array} List of all sub-graphs: [[nodes...], [nodes...]]
  17. */
  18. const findSubGraphs = (node, lane, recursion) => {
  19. recursion.callsCount++;
  20.  
  21. const { currentSubGraph, passedNodes, subGraphs } = recursion;
  22. const { nodes, edges, nodesMap } = lane;
  23. const nodeEdges = edges.filter((edge) => edge.start === node.id || edge.end === node.id);
  24.  
  25. // mark current sub-graph nodes and all nodes passed during search
  26. if (passedNodes.indexOf(node) < 0) {
  27. if (currentSubGraph.indexOf(node) < 0) {
  28. currentSubGraph.push(node);
  29. }
  30. passedNodes.push(node);
  31. }
  32. // continue walking through current sub-graph if checked node has references to other nodes
  33. if (nodeEdges.length) {
  34. const nextCheckedEdges = nodeEdges.filter((edge) => {
  35. return currentSubGraph.indexOf(nodesMap[edge.end]) < 0
  36. || currentSubGraph.indexOf(nodesMap[edge.start]) < 0;
  37. });
  38. nextCheckedEdges.forEach((edge) => {
  39. if (node.id !== edge.end) {
  40. return findSubGraphs(nodesMap[edge.end], lane, recursion);
  41. } else if (node.id !== edge.start) {
  42. return findSubGraphs(nodesMap[edge.start], lane, recursion);
  43. }
  44. });
  45. }
  46.  
  47. recursion.callsCount--;
  48.  
  49. // if no more calls were made, then current sub-graph search is completed
  50. if (recursion.callsCount === 0) {
  51. if (currentSubGraph.length) {
  52. subGraphs.push(currentSubGraph);
  53. }
  54.  
  55. // if all nodes were passed, exiting recursion
  56. if (passedNodes.length === nodes.length) {
  57. return subGraphs;
  58. }
  59.  
  60. // determine the next node which was not passed yet
  61. while (
  62. (recursion.startNodeIndex < nodes.length - 1)
  63. && (passedNodes.indexOf(nodes[recursion.startNodeIndex]) >= 0)
  64. ) {
  65. recursion.startNodeIndex++;
  66. }
  67. const nextNode = nodes[recursion.startNodeIndex];
  68.  
  69. // start search for next sub-graph
  70. recursion.currentSubGraph = [];
  71. return findSubGraphs(nextNode, lane, recursion);
  72. }
  73. };
  74.  
  75. export default function getLaneParts(nodes, edges) {
  76. if (!(nodes && nodes.length)) {
  77. return [];
  78. }
  79.  
  80. // build nodes map for faster access to node by id during sub-graphs search
  81. const nodesMap = nodes.reduce((result, node) => {
  82. result[node.id] = node;
  83. return result;
  84. }, {});
  85.  
  86. return findSubGraphs(
  87. nodes[0],
  88. {
  89. nodes,
  90. edges: edges || [],
  91. nodesMap,
  92. },
  93. {
  94. subGraphs: [],
  95. currentSubGraph: [],
  96. startNodeIndex: 0,
  97. passedNodes: [],
  98. callsCount: 0
  99. }
  100. );
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement