mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 07:06:54 +08:00
152 lines
3.8 KiB
Go
152 lines
3.8 KiB
Go
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package dynamic
|
|
|
|
import (
|
|
"bytes"
|
|
"cmp"
|
|
"fmt"
|
|
"io"
|
|
"slices"
|
|
"text/tabwriter"
|
|
|
|
"gonum.org/v1/gonum/graph/path/internal/testgraphs"
|
|
"gonum.org/v1/gonum/graph/simple"
|
|
)
|
|
|
|
// dumper implements a grid D* Lite statistics dump.
|
|
type dumper struct {
|
|
step int
|
|
|
|
dStarLite *DStarLite
|
|
grid *testgraphs.LimitedVisionGrid
|
|
|
|
w io.Writer
|
|
}
|
|
|
|
// dump writes a single step of a D* Lite path search to the dumper's io.Writer.
|
|
func (d *dumper) dump(withpath bool) {
|
|
if d == nil {
|
|
return
|
|
}
|
|
var pathStep map[int64]int
|
|
if withpath {
|
|
pathStep = make(map[int64]int)
|
|
path, _ := d.dStarLite.Path()
|
|
for i, n := range path {
|
|
pathStep[n.ID()] = i
|
|
}
|
|
}
|
|
fmt.Fprintf(d.w, "Step:%d kₘ=%v\n", d.step, d.dStarLite.keyModifier)
|
|
d.step++
|
|
w := tabwriter.NewWriter(d.w, 0, 0, 0, ' ', tabwriter.Debug)
|
|
rows, cols := d.grid.Grid.Dims()
|
|
for r := 0; r < rows; r++ {
|
|
if r == 0 {
|
|
for c := 0; c < cols; c++ {
|
|
if c != 0 {
|
|
fmt.Fprint(w, "\t")
|
|
}
|
|
fmt.Fprint(w, "-------------------")
|
|
}
|
|
fmt.Fprintln(w)
|
|
}
|
|
for ln := 0; ln < 6; ln++ {
|
|
for c := 0; c < cols; c++ {
|
|
if c != 0 {
|
|
fmt.Fprint(w, "\t")
|
|
}
|
|
n := d.dStarLite.model.Node(d.grid.NodeAt(r, c).ID()).(*dStarLiteNode)
|
|
switch ln {
|
|
case 0:
|
|
if n.ID() == d.grid.Location.ID() {
|
|
if d.grid.Grid.HasOpen(n.ID()) {
|
|
fmt.Fprintf(w, "id:%2d >@<", n.ID())
|
|
} else {
|
|
// Mark location as illegal.
|
|
fmt.Fprintf(w, "id:%2d >!<", n.ID())
|
|
}
|
|
} else if n.ID() == d.dStarLite.t.ID() {
|
|
fmt.Fprintf(w, "id:%2d G", n.ID())
|
|
// Mark goal cell as illegal.
|
|
if !d.grid.Grid.HasOpen(n.ID()) {
|
|
fmt.Fprint(w, "!")
|
|
}
|
|
} else if pathStep[n.ID()] > 0 {
|
|
fmt.Fprintf(w, "id:%2d %2d", n.ID(), pathStep[n.ID()])
|
|
// Mark path cells with an obstruction.
|
|
if !d.grid.Grid.HasOpen(n.ID()) {
|
|
fmt.Fprint(w, "!")
|
|
}
|
|
} else {
|
|
fmt.Fprintf(w, "id:%2d", n.ID())
|
|
// Mark cells with an obstruction.
|
|
if !d.grid.Grid.HasOpen(n.ID()) {
|
|
fmt.Fprint(w, " *")
|
|
}
|
|
}
|
|
case 1:
|
|
fmt.Fprintf(w, "h: %.4v", d.dStarLite.heuristic(n, d.dStarLite.Here()))
|
|
case 2:
|
|
fmt.Fprintf(w, "g: %.4v", n.g)
|
|
case 3:
|
|
fmt.Fprintf(w, "rhs:%.4v", n.rhs)
|
|
case 4:
|
|
if n.g != n.rhs {
|
|
fmt.Fprintf(w, "key:%.3f", n.key)
|
|
}
|
|
if !n.key.isBadKey() {
|
|
// Mark keys for nodes in the priority queue.
|
|
// We use NaN inequality for this check since all
|
|
// keys not in the queue must have their key set
|
|
// to badKey.
|
|
//
|
|
// This should always mark cells where key is
|
|
// printed.
|
|
fmt.Fprint(w, "*")
|
|
}
|
|
if n.g > n.rhs {
|
|
fmt.Fprint(w, "^")
|
|
}
|
|
if n.g < n.rhs {
|
|
fmt.Fprint(w, "v")
|
|
}
|
|
default:
|
|
fmt.Fprint(w, "-------------------")
|
|
}
|
|
}
|
|
fmt.Fprintln(w)
|
|
}
|
|
}
|
|
w.Flush()
|
|
fmt.Fprintln(d.w)
|
|
}
|
|
|
|
// printEdges pretty prints the given edges to the dumper's io.Writer using the provided
|
|
// format string. The edges are first formatted to a string, so the format string must use
|
|
// the %s verb to indicate where the edges are to be printed.
|
|
func (d *dumper) printEdges(format string, edges []simple.WeightedEdge) {
|
|
if d == nil {
|
|
return
|
|
}
|
|
var buf bytes.Buffer
|
|
slices.SortFunc(edges, func(a, b simple.WeightedEdge) int {
|
|
if n := cmp.Compare(a.From().ID(), b.From().ID()); n != 0 {
|
|
return n
|
|
}
|
|
return cmp.Compare(a.To().ID(), b.To().ID())
|
|
})
|
|
for i, e := range edges {
|
|
if i != 0 {
|
|
fmt.Fprint(&buf, ", ")
|
|
}
|
|
fmt.Fprintf(&buf, "%d->%d:%.4v", e.From().ID(), e.To().ID(), e.Weight())
|
|
}
|
|
if len(edges) == 0 {
|
|
fmt.Fprint(&buf, "none")
|
|
}
|
|
fmt.Fprintf(d.w, format, buf.Bytes())
|
|
}
|