Skip to content

Commit 51a1789

Browse files
committed
Refactoring Graph and Fixing Floyd-Warshall
1 parent b894c5d commit 51a1789

File tree

4 files changed

+65
-77
lines changed

4 files changed

+65
-77
lines changed

data-structures/graph.js renamed to data-structures/graph/graph.js

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,19 @@
22
var __importDefault = (this && this.__importDefault) || function (mod) {
33
return (mod && mod.__esModule) ? mod : { "default": mod };
44
};
5-
const queue_1 = __importDefault(require("./basics/queue"));
6-
const stack_1 = __importDefault(require("./basics/stack"));
7-
const minHeap_1 = __importDefault(require("./heaps/minHeap"));
5+
const queue_1 = __importDefault(require("../basics/queue"));
6+
const stack_1 = __importDefault(require("../basics/stack"));
7+
const minHeap_1 = __importDefault(require("../heaps/minHeap"));
88
// import FibonacciHeap from "./heaps/fibonacciHeap";
99
// import FHNode from "./heaps/fHNode";
10-
const listSet_1 = __importDefault(require("./disjoint-sets/listSet"));
11-
const forestSet_1 = __importDefault(require("./disjoint-sets/forestSet"));
10+
const listSet_1 = __importDefault(require("../disjoint-sets/listSet"));
11+
const forestSet_1 = __importDefault(require("../disjoint-sets/forestSet"));
1212
const fs_1 = __importDefault(require("fs"));
13+
const vertex_1 = require("./vertex");
1314
// Returns a random number between [min,max)
1415
const random = (min, max) => {
1516
return Math.floor(Math.random() * (max - min)) + min;
1617
};
17-
const isWeighted = (v) => {
18-
if (v.weight)
19-
return true;
20-
return false;
21-
};
2218
class Graph {
2319
constructor(directed = false) {
2420
this.directed = directed;
@@ -31,15 +27,15 @@ class Graph {
3127
for (let [u, vertexList] of this.list) {
3228
for (let v of vertexList) {
3329
if (!this.directed) {
34-
if (isWeighted(v)) {
30+
if (vertex_1.isWeighted(v)) {
3531
console.log(`${u} - ${v.node} - ${v.weight}`);
3632
}
3733
else {
3834
console.log(`${u} - ${v.node}`);
3935
}
4036
}
4137
else {
42-
if (isWeighted(v)) {
38+
if (vertex_1.isWeighted(v)) {
4339
console.log(`${u} -> ${v.node} - ${v.weight}`);
4440
}
4541
else {
@@ -132,7 +128,7 @@ class Graph {
132128
const g = new Graph(true);
133129
for (let [u, vertexList] of this.list) {
134130
for (let v in vertexList) {
135-
if (isWeighted(vertexList[v])) {
131+
if (vertex_1.isWeighted(vertexList[v])) {
136132
g.addVertecesAndEdge(vertexList[v].node, u, vertexList[v].weight);
137133
}
138134
else {
@@ -547,11 +543,14 @@ class Graph {
547543
// Returns the distance from all pair of vertices (u,v) in V
548544
// negative costs are allowed
549545
// use parents (predecessor pointers) to traverse the cycle
550-
// FIXME:
546+
// Also returns the last node used in set K
551547
this.floydWarshall = () => {
552548
let costs = new Map();
553549
// predecessor pointers
554550
const parents = new Map();
551+
const keys = [...this.list.keys()];
552+
// last vertex in K
553+
let oldK = keys[0];
555554
// Initialize maps
556555
// i: starter vertex, j: target vertex
557556
// K: set of allowed vertex, k: last vertex in K
@@ -567,17 +566,13 @@ class Graph {
567566
}
568567
if (!costs.get(i).get(j)) {
569568
costs.get(i).set(j, new Map());
570-
parents.get(i).set(j, new Map());
571-
}
572-
if (!costs.get(i).get(j).get(i)) {
573-
costs.get(i).get(j).set(i, new Map());
574569
}
575570
if (i === j) {
576-
costs.get(i).get(j).set(i, 0);
571+
costs.get(i).get(j).set(oldK, 0);
577572
parents.get(i).set(i, null);
578573
}
579574
else {
580-
costs.get(i).get(j).set(i, Infinity);
575+
costs.get(i).get(j).set(oldK, Infinity);
581576
}
582577
}
583578
}
@@ -586,20 +581,13 @@ class Graph {
586581
for (let [i, vertexList] of this.list) {
587582
for (let neighbour in vertexList) {
588583
const w = vertexList[neighbour];
589-
costs.get(i).get(w.node).set(i, w.weight);
584+
costs.get(i).get(w.node).set(oldK, w.weight);
590585
}
591586
}
592-
// FIXME: Use K set again
593-
// let oldK = "0";
594587
// to expand K to the next vertex of this.list
595-
for (let [k] of this.list) {
596-
let oldK = k;
588+
for (let k of keys) {
597589
for (let [i] of this.list) {
598590
for (let [j] of this.list) {
599-
// to initialize a new map for this new set K
600-
if (!costs.get(i).get(j).get(k)) {
601-
costs.get(i).get(j).set(k, new Map());
602-
}
603591
// min {path without new k (as intermediary), path i to k + path k to j}
604592
const lastD = costs.get(i).get(j).get(oldK);
605593
const d = costs.get(i).get(k).get(oldK) + costs.get(k).get(j).get(oldK);
@@ -615,7 +603,7 @@ class Graph {
615603
// update oldK
616604
oldK = k;
617605
}
618-
return { costs, parents };
606+
return { costs, parents, oldK };
619607
};
620608
// TODO: Johnson's Algorithm?
621609
// TODO: USE FIBONACCI HEAP (DECREASE KEY)

data-structures/graph.ts renamed to data-structures/graph/graph.ts

Lines changed: 30 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
1-
import Queue from "./basics/queue";
2-
import Stack from "./basics/stack";
3-
import Node from "./basics/node";
4-
import MinHeap from "./heaps/minHeap";
5-
import BHNode from "./heaps/bHNode";
1+
import Queue from "../basics/queue";
2+
import Stack from "../basics/stack";
3+
import Node from "../basics/node";
4+
import MinHeap from "../heaps/minHeap";
5+
import BHNode from "../heaps/bHNode";
66
// import FibonacciHeap from "./heaps/fibonacciHeap";
77
// import FHNode from "./heaps/fHNode";
8-
import ListSet from "./disjoint-sets/listSet";
9-
import ForestSet from "./disjoint-sets/forestSet";
8+
import ListSet from "../disjoint-sets/listSet";
9+
import ForestSet from "../disjoint-sets/forestSet";
1010
import fs from "fs";
11+
import { Vertex, isWeighted } from "./vertex";
1112

1213
// Returns a random number between [min,max)
1314
const random = (min: number, max: number) => {
1415
return Math.floor(Math.random() * (max - min)) + min;
1516
};
1617

17-
interface Vertex<T> {
18-
node: T;
19-
weight?: number;
20-
}
21-
22-
const isWeighted = <T>(v: Vertex<T>) => {
23-
if (v.weight) return true;
24-
return false;
25-
};
26-
2718
class Graph<T> {
2819
// list adj: Map(key,array of vertex)
2920
list: Map<T, Vertex<T>[]>;
@@ -747,11 +738,14 @@ class Graph<T> {
747738
// Returns the distance from all pair of vertices (u,v) in V
748739
// negative costs are allowed
749740
// use parents (predecessor pointers) to traverse the cycle
750-
// FIXME:
741+
// Also returns the last node used in set K
751742
floydWarshall = () => {
752-
let costs = new Map();
743+
let costs = new Map<T, Map<T, Map<T, number>>>();
753744
// predecessor pointers
754-
const parents = new Map();
745+
const parents = new Map<T, Map<T, T | null>>();
746+
const keys = [...this.list.keys()];
747+
// last vertex in K
748+
let oldK = keys[0];
755749
// Initialize maps
756750
// i: starter vertex, j: target vertex
757751
// K: set of allowed vertex, k: last vertex in K
@@ -762,21 +756,17 @@ class Graph<T> {
762756
for (let [i] of this.list) {
763757
for (let [j] of this.list) {
764758
if (!costs.get(i)) {
765-
costs.set(i, new Map());
766-
parents.set(i, new Map());
767-
}
768-
if (!costs.get(i).get(j)) {
769-
costs.get(i).set(j, new Map());
770-
parents.get(i).set(j, new Map());
759+
costs.set(i, new Map<T, Map<T, number>>());
760+
parents.set(i, new Map<T, T | null>());
771761
}
772-
if (!costs.get(i).get(j).get(i)) {
773-
costs.get(i).get(j).set(i, new Map());
762+
if (!costs.get(i)!.get(j)) {
763+
costs.get(i)!.set(j, new Map<T, number>());
774764
}
775765
if (i === j) {
776-
costs.get(i).get(j).set(i, 0);
777-
parents.get(i).set(i, null);
766+
costs.get(i)!.get(j)!.set(oldK, 0);
767+
parents.get(i)!.set(i, null);
778768
} else {
779-
costs.get(i).get(j).set(i, Infinity);
769+
costs.get(i)!.get(j)!.set(oldK, Infinity);
780770
}
781771
}
782772
}
@@ -785,36 +775,29 @@ class Graph<T> {
785775
for (let [i, vertexList] of this.list) {
786776
for (let neighbour in vertexList) {
787777
const w = vertexList[neighbour];
788-
costs.get(i).get(w.node).set(i, w.weight!);
778+
costs.get(i)!.get(w.node)!.set(oldK, w.weight!);
789779
}
790780
}
791-
// FIXME: Use K set again
792-
// let oldK = "0";
793781
// to expand K to the next vertex of this.list
794-
for (let [k] of this.list) {
795-
let oldK = k;
782+
for (let k of keys) {
796783
for (let [i] of this.list) {
797784
for (let [j] of this.list) {
798-
// to initialize a new map for this new set K
799-
if (!costs.get(i).get(j).get(k)) {
800-
costs.get(i).get(j).set(k, new Map());
801-
}
802785
// min {path without new k (as intermediary), path i to k + path k to j}
803-
const lastD = costs.get(i).get(j).get(oldK);
804-
const d =
805-
costs.get(i).get(k).get(oldK) + costs.get(k).get(j).get(oldK);
786+
const lastD = costs.get(i)!.get(j)!.get(oldK)!;
787+
const d: number =
788+
costs.get(i)!.get(k)!.get(oldK)! + costs.get(k)!.get(j)!.get(oldK)!;
806789
if (d < lastD) {
807-
costs.get(i).get(j).set(k, d);
808-
parents.get(i).set(j, k);
790+
costs.get(i)!.get(j)!.set(k, d);
791+
parents.get(i)!.set(j, k);
809792
} else {
810-
costs.get(i).get(j).set(k, lastD);
793+
costs.get(i)!.get(j)!.set(k, lastD);
811794
}
812795
}
813796
}
814797
// update oldK
815798
oldK = k;
816799
}
817-
return { costs, parents };
800+
return { costs, parents, oldK };
818801
};
819802

820803
// TODO: Johnson's Algorithm?

data-structures/graph/vertex.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.isWeighted = void 0;
4+
exports.isWeighted = (v) => {
5+
if (v.weight)
6+
return true;
7+
return false;
8+
};

data-structures/graph/vertex.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface Vertex<T> {
2+
node: T;
3+
weight?: number;
4+
}
5+
6+
export const isWeighted = <T>(v: Vertex<T>) => {
7+
if (v.weight) return true;
8+
return false;
9+
};

0 commit comments

Comments
 (0)