@@ -10,7 +10,6 @@ const minHeap_1 = __importDefault(require("../heaps/minHeap"));
1010const listSet_1 = __importDefault ( require ( "../disjoint-sets/listSet" ) ) ;
1111const forestSet_1 = __importDefault ( require ( "../disjoint-sets/forestSet" ) ) ;
1212const fs_1 = __importDefault ( require ( "fs" ) ) ;
13- const vertex_1 = require ( "./vertex" ) ;
1413// Returns a random number between [min,max)
1514const random = ( min , max ) => {
1615 return Math . floor ( Math . random ( ) * ( max - min ) ) + min ;
@@ -27,20 +26,10 @@ class Graph {
2726 for ( let [ u , vertexList ] of this . list ) {
2827 for ( let v of vertexList ) {
2928 if ( ! this . directed ) {
30- if ( vertex_1 . isWeighted ( v ) ) {
31- console . log ( `${ u } - ${ v . node } - ${ v . weight } ` ) ;
32- }
33- else {
34- console . log ( `${ u } - ${ v . node } ` ) ;
35- }
29+ console . log ( `${ u } - ${ v . node } - ${ v . weight } ` ) ;
3630 }
3731 else {
38- if ( vertex_1 . isWeighted ( v ) ) {
39- console . log ( `${ u } -> ${ v . node } - ${ v . weight } ` ) ;
40- }
41- else {
42- console . log ( `${ u } -> ${ v . node } ` ) ;
43- }
32+ console . log ( `${ u } -> ${ v . node } - ${ v . weight } ` ) ;
4433 }
4534 }
4635 }
@@ -128,12 +117,7 @@ class Graph {
128117 const g = new Graph ( true ) ;
129118 for ( let [ u , vertexList ] of this . list ) {
130119 for ( let v in vertexList ) {
131- if ( vertex_1 . isWeighted ( vertexList [ v ] ) ) {
132- g . addVertecesAndEdge ( vertexList [ v ] . node , u , vertexList [ v ] . weight ) ;
133- }
134- else {
135- g . addVertecesAndEdge ( vertexList [ v ] . node , u ) ;
136- }
120+ g . addVertecesAndEdge ( vertexList [ v ] . node , u , vertexList [ v ] . weight ) ;
137121 }
138122 }
139123 return g ;
@@ -186,19 +170,6 @@ class Graph {
186170 if ( ! this . contains ( u ) || ! this . contains ( v ) )
187171 return false ;
188172 let vertexList = this . list . get ( u ) ;
189- // unweighted graph
190- if ( weight === 0 ) {
191- vertexList . push ( { node : v } ) ;
192- this . list . set ( u , vertexList ) ;
193- if ( ! this . directed ) {
194- // vertex list of v
195- let vvl = this . list . get ( v ) ;
196- vvl . push ( { node : u } ) ;
197- this . list . set ( v , vvl ) ;
198- }
199- return this ;
200- }
201- // weighted graph
202173 vertexList . push ( { node : v , weight } ) ;
203174 this . list . set ( u , vertexList ) ;
204175 if ( ! this . directed ) {
@@ -489,11 +460,14 @@ class Graph {
489460 }
490461 }
491462 }
492- console . log ( `dequeues: ${ dequeues } ,size: ${ this . size } , h.size: ${ heap . size } ` ) ;
463+ // console.log(
464+ // `dequeues: ${dequeues},size: ${this.size}, h.size: ${heap.size}`
465+ // );
493466 return { distances, parents } ;
494467 } ;
495468 // Returns the distance from s to each vertex and their parents O(mn)
496469 // negative costs are allowed
470+ // SSSP (Single Source Shortest Problemß)
497471 // detect negative cycles: boolean output (cycle)
498472 // use parents (predecessor pointers) to traverse the cycle
499473 this . bellmanFord = ( s ) => {
@@ -504,6 +478,7 @@ class Graph {
504478 const parents = new Map ( ) ;
505479 // to stop earlier
506480 let stop = true ;
481+ // i: number of edges allowed
507482 // for i =0, all dist from s to vertex are infinity
508483 for ( let [ vertex ] of this . list ) {
509484 if ( vertex !== s ) {
@@ -542,6 +517,7 @@ class Graph {
542517 } ;
543518 // Returns the distance from all pair of vertices (u,v) in V
544519 // negative costs are allowed
520+ // APSP (All Pairs Shortest Path)
545521 // use parents (predecessor pointers) to traverse the cycle
546522 // Also returns the last node used in set K
547523 this . floydWarshall = ( ) => {
@@ -585,6 +561,7 @@ class Graph {
585561 }
586562 }
587563 // to expand K to the next vertex of this.list
564+ // O(n3)
588565 for ( let k of keys ) {
589566 for ( let [ i ] of this . list ) {
590567 for ( let [ j ] of this . list ) {
@@ -605,7 +582,72 @@ class Graph {
605582 }
606583 return { costs, parents, oldK } ;
607584 } ;
608- // TODO: Johnson's Algorithm?
585+ // Returns the distance from all pair of vertices (u,v) in V
586+ // negative costs are allowed
587+ // Report a negative Cycle (cycle: true)
588+ // APSP (All Pairs Shortest Path)
589+ // use parents (predecessor pointers) to traverse the cycle
590+ // O(mnlog(n))
591+ this . johnson = ( s ) => {
592+ // map distance between vertex u to v
593+ const dist = new Map ( ) ;
594+ // map parent of v when u is the start vertex
595+ const par = new Map ( ) ;
596+ // Form G': equal to G, only add vertex <s>
597+ const newG = new Graph ( true ) ;
598+ // O(m)
599+ for ( let [ u , vertexList ] of this . list ) {
600+ for ( let v of vertexList ) {
601+ newG . addVertecesAndEdge ( u , v . node , v . weight ) ;
602+ }
603+ }
604+ // Add a new vertex <s> connect to all v in G, with edge cost = 0
605+ // O(n)
606+ newG . addVertex ( s ) ;
607+ for ( let [ v ] of this . list ) {
608+ if ( s !== v )
609+ newG . addEdge ( s , v , 0 ) ;
610+ }
611+ // runs BF in G' using <s> as start vertex
612+ // BF: O(mn)
613+ const { costs, cycle } = newG . bellmanFord ( s ) ;
614+ // check for a negative cycle
615+ if ( cycle )
616+ return { cycle : true } ;
617+ // calcule ce' = ce + pu - pv
618+ // pu and pv are the costs from BF for a pair (u,v) of vertex
619+ // O(m)
620+ for ( let [ u , vertexList ] of this . list ) {
621+ for ( let v of vertexList ) {
622+ const newCost = v . weight + costs . get ( u ) - costs . get ( v . node ) ;
623+ v . weight = newCost ;
624+ this . list . set ( u , vertexList ) ;
625+ }
626+ }
627+ // run dijkstra for each vertex (using ce')
628+ // ce' is not negative, but dijkstra will retun: d'(u,v)
629+ // d'(u,v) = d(u,v) + pu - pv
630+ // Dijkstra n times: O(nmlog(n))
631+ for ( let [ u ] of this . list ) {
632+ const { distances, parents } = this . dijkstra ( u ) ;
633+ dist . set ( u , distances ) ;
634+ par . set ( u , parents ) ;
635+ }
636+ // we nedd to calculate d(u,v)
637+ // d(u,v) = d'(u,v) - pu + pv
638+ // O(n2)
639+ for ( let [ u ] of this . list ) {
640+ for ( let [ v ] of this . list ) {
641+ if ( u !== v ) {
642+ const d = dist . get ( u ) . get ( v ) ;
643+ const pu = costs . get ( u ) ;
644+ const pv = costs . get ( v ) ;
645+ dist . get ( u ) . set ( v , d - pu + pv ) ;
646+ }
647+ }
648+ }
649+ return { costs : dist , parents : par , cycle } ;
650+ } ;
609651 // TODO: USE FIBONACCI HEAP (DECREASE KEY)
610652 // Returns the MST and its cost
611653 this . prim = ( s ) => {
@@ -849,7 +891,8 @@ Graph.createListAdjWeighted = (file) => {
849891// File is the adj list of this Graph
850892// FORMAT: <first vertex u>' '<second vertex v>
851893// it is a drirected graph, the edge goes from u to v, i.e.: u -> v
852- Graph . createDirected = ( file , w = false ) => {
894+ // d to allow duplication
895+ Graph . createDirected = ( file , w = false , d = false ) => {
853896 // set this graph as directed
854897 const g = new Graph ( true ) ;
855898 const data = fs_1 . default . readFileSync ( file , { encoding : "utf8" , flag : "r" } ) ;
@@ -862,11 +905,11 @@ Graph.createDirected = (file, w = false) => {
862905 else {
863906 split = line . trim ( ) . split ( " " ) ;
864907 if ( ! w ) {
865- g . addVertecesAndEdge ( split [ 0 ] , split [ 1 ] ) ;
908+ g . addVertecesAndEdge ( split [ 0 ] , split [ 1 ] , 0 , d ) ;
866909 }
867910 else {
868911 // Avoid duplications!
869- g . addVertecesAndEdge ( split [ 0 ] , split [ 1 ] , parseInt ( split [ 2 ] ) , false ) ;
912+ g . addVertecesAndEdge ( split [ 0 ] , split [ 1 ] , parseInt ( split [ 2 ] ) , d ) ;
870913 }
871914 line = "" ;
872915 }
0 commit comments