-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
95 lines (73 loc) · 2.1 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package main
import (
"fmt"
"os"
"route-planning/graph"
"route-planning/graphio"
"route-planning/shortestpath"
"time"
"github.com/jessevdk/go-flags"
)
type FileArg struct {
File string
}
type DijkstraCommand struct {
Source int `short:"s" long:"source" required:"true" description:"source node"`
Target int `short:"t" long:"target" required:"true" description:"target node"`
Bidirectional bool `short:"b" long:"bidirect" description:"use bidirectional mode"`
FileArg FileArg `positional-args:"true" required:"true"`
}
var cli struct {
Dijkstra DijkstraCommand `command:"dijkstra"`
Format string `short:"f" long:"format" description:"the input format" choice:"mtx" choice:"dimacs" default:"dimacs"`
Verbose bool `short:"v" long:"verbose" description:"display additional information"`
}
func main() {
p := flags.NewParser(&cli, flags.Default)
if _, err := p.Parse(); err != nil {
if flags.WroteHelp(err) {
return
}
p.WriteHelp(os.Stderr)
os.Exit(1)
}
var in graphio.GraphInput
switch cli.Format {
case "dimacs":
in = graphio.NewDIMANCSInput(cli.Dijkstra.FileArg.File)
case "mtx":
in = graphio.NewMTXInput(cli.Dijkstra.FileArg.File)
}
edges, n, err := in.LoadGraph()
if err != nil {
fmt.Printf("Error loading graph from input: %v\n", err)
os.Exit(1)
}
fmt.Printf("Loaded %d edges and %d nodes\n", len(edges), n)
g := graph.NewAdjacencyList(edges, n)
var algo shortestpath.Algorithm
algo = &shortestpath.Dijkstra{Graph: g}
if cli.Dijkstra.Bidirectional {
algo = &shortestpath.BidirectDijkstra{
ForwardGraph: g,
BackwardGraph: g.Reverted(),
}
}
s, t := graph.Node(cli.Dijkstra.Source-1), graph.Node(cli.Dijkstra.Target-1)
start := time.Now()
c, path := algo.Pair(s, t)
took := time.Since(start)
fmt.Printf("Shortest path algorithm took: %v\n", took)
if len(path) == 0 {
fmt.Printf("No path from %d to %d\n", s+1, t+1)
os.Exit(1)
}
fmt.Printf("Cost: %f, Hops: %d\n", c, len(path))
if cli.Verbose {
pathNodes := []graph.Node{path[0].From + 1}
for _, e := range path {
pathNodes = append(pathNodes, e.To+1)
}
fmt.Printf("%v\n", pathNodes)
}
}