Advertisement
Guest User

Untitled

a guest
Sep 16th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.44 KB | None | 0 0
  1. <html>
  2. <body>
  3. <div id="output">
  4.  
  5. </div>
  6. <script>
  7. function NodeSet() {
  8. this.array = [];
  9. }
  10.  
  11. NodeSet.prototype.clear = function() {
  12. this.array = [];
  13. }
  14.  
  15. NodeSet.prototype.add = function(node) {
  16. this.array[node.id] = node;
  17. }
  18.  
  19. NodeSet.prototype.includes = function(node) {
  20. return this.array[node.id] !== undefined;
  21. }
  22.  
  23. NodeSet.prototype.size = function() {
  24. return this.array.length;
  25. }
  26.  
  27. function Node(id) {
  28. this.id = id;
  29. this.children = [];
  30. this.parents = [];
  31. }
  32.  
  33. Node.prototype.toString = function() {
  34. return "[Node " + this.id + "]";
  35. }
  36.  
  37. function nodeEq(nodeA, nodeB) {
  38. return nodeA.id === nodeB.id;
  39. }
  40.  
  41. function connect(tail, head) {
  42. tail.children.push(head);
  43. head.parents.push(tail);
  44. }
  45.  
  46. function BuildPath(sourceNode, meetingNode, backwardStack) {
  47. let path = BidirectionalIterativeDeepeningDepthFirstSearch(sourceNode,
  48. meetingNode);
  49. path.splice(-1, 1);
  50. path.push(...backwardStack);
  51. return path;
  52. }
  53.  
  54. function DepthLimitedSearchForward(node, depth, frontier) {
  55. if (depth === 0) {
  56. frontier.add(node);
  57. return;
  58. }
  59.  
  60. node.children.forEach(function(child) {
  61. DepthLimitedSearchForward(child, depth - 1, frontier);
  62. });
  63. }
  64.  
  65. function DepthLimitedSearchBackward(node, depth, backwardStack, frontier) {
  66. backwardStack.unshift(node);
  67.  
  68. if (depth === 0) {
  69. if (frontier.includes(node)) {
  70. return node;
  71. }
  72.  
  73. backwardStack.shift();
  74. return null;
  75. }
  76.  
  77. for (var i = 0; i !== node.parents.length; i++) {
  78. let parent = node.parents[i];
  79. let meetingNode = DepthLimitedSearchBackward(parent, depth - 1, backwardStack, frontier);
  80.  
  81. if (meetingNode !== null) {
  82. return meetingNode;
  83. }
  84. }
  85.  
  86. backwardStack.shift();
  87. return null;
  88. }
  89.  
  90. function BidirectionalIterativeDeepeningDepthFirstSearch(sourceNode,
  91. targetNode) {
  92. if (sourceNode.id === targetNode.id) {
  93. return [sourceNode];
  94. }
  95.  
  96. let frontier = new NodeSet();
  97. let backwardStack = [];
  98. let depth = 0;
  99.  
  100. while (true) {
  101. DepthLimitedSearchForward(sourceNode, depth, frontier);
  102.  
  103. for (var i = 0; i < 2; i++) {
  104. let meetingNode = DepthLimitedSearchBackward(targetNode,
  105. depth + i,
  106. backwardStack,
  107. frontier);
  108.  
  109. if (meetingNode !== null) {
  110. return BuildPath(sourceNode,
  111. meetingNode,
  112. backwardStack);
  113. }
  114.  
  115. backwardStack = [];
  116. }
  117.  
  118. frontier.clear();
  119. depth++;
  120. }
  121. }
  122.  
  123. function DequeNode(elem) {
  124. this.next = undefined;
  125. this.elem = elem;
  126. }
  127.  
  128. function Deque() {
  129. this.head = undefined;
  130. this.tail = undefined;
  131. this.size = 0;
  132. }
  133.  
  134. Deque.prototype.shift = function() {
  135. let ret = this.head.elem;
  136. this.head = this.head.next;
  137. this.size--;
  138. return ret;
  139. }
  140.  
  141. Deque.prototype.push = function(elem) {
  142. let newNode = new DequeNode(elem);
  143.  
  144. if (this.head) {
  145. this.tail.next = newNode;
  146. } else {
  147. this.head = newNode;
  148. }
  149.  
  150. this.size++;
  151. this.tail = newNode;
  152. }
  153.  
  154. Deque.prototype.length = function() {
  155. return this.size;
  156. }
  157.  
  158. Deque.prototype.front = function() {
  159. return this.head.elem;
  160. }
  161.  
  162. let NULL = "NULL";
  163.  
  164. function tracebackPath(touchNode, parentsA, parentsB) {
  165. let path = [];
  166. let current = touchNode;
  167.  
  168. while (current != NULL) {
  169. path.push(current);
  170. current = parentsA.get(current);
  171. }
  172.  
  173. path.reverse();
  174.  
  175. if (parentsB) {
  176. current = parentsB.get(touchNode);
  177.  
  178. while (current != NULL) {
  179. path.push(current);
  180. current = parentsB.get(current);
  181. }
  182. }
  183.  
  184. return path;
  185. }
  186.  
  187. function NodeMap() {
  188. this.array = [];
  189. this.size = 0;
  190. }
  191.  
  192. NodeMap.prototype.put = function(key, value) {
  193. if (this.array[key.id] === undefined) {
  194. this.array[key.id] = value;
  195. this.size++;
  196. }
  197. }
  198.  
  199. NodeMap.prototype.get = function(key) {
  200. return this.array[key.id];
  201. }
  202.  
  203. NodeMap.prototype.containsKey = function(key) {
  204. return this.array[key.id] !== undefined;
  205. }
  206.  
  207. NodeMap.prototype.length = function() {
  208. return this.size;
  209. }
  210.  
  211. function BidirectionalBreadthFirstSearch(s, t) {
  212. let queueA = new Deque();
  213. let queueB = new Deque();
  214.  
  215. let parentsA = new NodeMap();
  216. let parentsB = new NodeMap();
  217.  
  218. let distanceA = new NodeMap();
  219. let distanceB = new NodeMap();
  220.  
  221. queueA.push(s);
  222. queueB.push(t);
  223.  
  224. parentsA.put(s, NULL);
  225. parentsB.put(t, NULL);
  226.  
  227. distanceA.put(s, 0);
  228. distanceB.put(t, 0);
  229.  
  230. let bestCost = 1000 * 1000 * 1000;
  231. let touchNode = undefined;
  232.  
  233. while (queueA.length() > 0 && queueB.length() > 0) {
  234. let distA = distanceA.get(queueA.front());
  235. let distB = distanceB.get(queueB.front());
  236.  
  237. if (touchNode && bestCost < distA + distB) {
  238. return tracebackPath(touchNode,
  239. parentsA,
  240. parentsB);
  241. }
  242.  
  243. if (distanceA.length() < distanceB.length()) {
  244. let current = queueA.shift();
  245.  
  246. for (let i = 0; i < current.children.length; i++) {
  247. let child = current.children[i];
  248.  
  249. if (!distanceA.containsKey(child)) {
  250. distanceA.put(child, distanceA.get(current) + 1);
  251. parentsA.put(child, current);
  252. queueA.push(child);
  253.  
  254. if (distanceB.containsKey(child)
  255. &&
  256. bestCost > distanceA.get(child) + distanceB.get(child)) {
  257. bestCost = distanceA.get(child) + distanceB.get(child);
  258. touchNode = child;
  259. }
  260. }
  261. }
  262. } else {
  263. let current = queueB.shift();
  264.  
  265. for (let i = 0; i < current.parents.length; i++) {
  266. let parent = current.parents[i];
  267.  
  268. if (!distanceB.containsKey(parent)) {
  269. distanceB.put(parent, distanceB.get(current) + 1);
  270. parentsB.put(parent, current);
  271. queueB.push(parent);
  272.  
  273. if (distanceA.containsKey(parent)
  274. &&
  275. bestCost > distanceA.get(parent) + distanceB.get(parent)) {
  276. bestCost = distanceA.get(parent) + distanceB.get(parent);
  277. touchNode = parent;
  278. }
  279. }
  280. }
  281. }
  282. }
  283.  
  284. return [];
  285. }
  286.  
  287. function BreadthFirstSearch(source, target) {
  288. let queue = new Deque();
  289. let parents = new NodeMap();
  290.  
  291. queue.push(source);
  292. parents.put(source, NULL);
  293.  
  294. while (queue.length() > 0) {
  295. let current = queue.shift();
  296.  
  297. if (current.id === target.id) {
  298. return tracebackPath(current, parents, undefined);
  299. }
  300.  
  301. for (let i = 0; i < current.children.length; i++) {
  302. let child = current.children[i];
  303.  
  304. if (!parents.containsKey(child)) {
  305. parents.put(child, current);
  306. queue.push(child);
  307. }
  308. }
  309. }
  310.  
  311. return [];
  312. }
  313.  
  314. function createGraph(nodes, arcs) {
  315. let graph = [];
  316.  
  317. for (var id = 0; id < nodes; id++) {
  318. graph.push(new Node(id));
  319. }
  320.  
  321. for (var i = 0; i < arcs; i++) {
  322. let tailIndex = Math.floor(Math.random() * nodes);
  323. let headIndex = Math.floor(Math.random() * nodes);
  324. connect(graph[tailIndex], graph[headIndex]);
  325. }
  326.  
  327. return graph;
  328. }
  329.  
  330. let outputDiv = document.getElementById("output");
  331.  
  332. const NODES = 1000000;
  333. const ARCS = 5000000;
  334. const graph = createGraph(NODES, ARCS);
  335.  
  336. let sourceIndex = Math.floor(Math.random() * NODES);
  337. let targetIndex = Math.floor(Math.random() * NODES);
  338.  
  339. let sourceNode = graph[sourceIndex];
  340. let targetNode = graph[targetIndex];
  341.  
  342. console.log("Source node: " + sourceNode);
  343. console.log("Target node: " + targetNode);
  344. outputDiv.innerHTML += "Source node: " + sourceNode + "<br>" +
  345. "Target node: " + targetNode + "<br>";
  346.  
  347. outputDiv.innerHTML += "<br>BIDDFS:";
  348.  
  349. var startTime = new Date().getMilliseconds();
  350. var path = BidirectionalIterativeDeepeningDepthFirstSearch(sourceNode,
  351. targetNode);
  352. var endTime = new Date().getMilliseconds();
  353. var num = 1;
  354.  
  355. for (var i = 0; i < path.length; i++) {
  356. let node = path[i];
  357. outputDiv.innerHTML += "<br>" + num + ": " + node;
  358. console.log(num++ + ": " + node);
  359. }
  360.  
  361. let duration = endTime - startTime;
  362. console.log("Duration: " + duration + " ms.");
  363. outputDiv.innerHTML += "<br>Duration: " + duration + " ms.";
  364. outputDiv.innerHTML += "<br><br>Bidirectional BFS:";
  365.  
  366. startTime = new Date().getMilliseconds();
  367. var path2 = BidirectionalBreadthFirstSearch(sourceNode,
  368. targetNode);
  369. endTime = new Date().getMilliseconds();
  370. duration = endTime - startTime;
  371. num = 1;
  372.  
  373. for (var i = 0; i < path2.length; i++) {
  374. let node = path2[i];
  375. outputDiv.innerHTML += "<br>" + num + ": " + node;
  376. console.log(num++ + ": " + node);
  377. }
  378.  
  379. console.log("Duration: " + (endTime - startTime) + " ms.");
  380. outputDiv.innerHTML += "<br>Duration: " + duration + " ms.";
  381. outputDiv.innerHTML += "<br><br>BFS:";
  382.  
  383. startTime = new Date().getMilliseconds();
  384. var path3 = BreadthFirstSearch(sourceNode,
  385. targetNode);
  386. endTime = new Date().getMilliseconds();
  387. duration = endTime - startTime;
  388. num = 1;
  389.  
  390. for (var i = 0; i < path3.length; i++) {
  391. let node = path3[i];
  392. outputDiv.innerHTML += "<br>" + num + ": " + node;
  393. console.log(num++ + ": " + node);
  394. }
  395.  
  396. console.log("Duration: " + duration + " ms.");
  397. outputDiv.innerHTML += "<br>Duration: " + duration + " ms.";
  398. </script>
  399. </body>
  400. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement