1. update clientset, deepcopy using code-generator
2. add a dummy file tools.go to force "go mod vendor" to see code-generator as dependencies 3. add a script to update CRD 4. add a README to document CRD updating steps run go mod tidy update README
This commit is contained in:
301
vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go
generated
vendored
Normal file
301
vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go
generated
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/ordered"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
var (
|
||||
dm *DirectedMatrix
|
||||
|
||||
_ graph.Graph = dm
|
||||
_ graph.Directed = dm
|
||||
_ edgeSetter = dm
|
||||
_ weightedEdgeSetter = dm
|
||||
)
|
||||
|
||||
// DirectedMatrix represents a directed graph using an adjacency
|
||||
// matrix such that all IDs are in a contiguous block from 0 to n-1.
|
||||
// Edges are stored implicitly as an edge weight, so edges stored in
|
||||
// the graph are not recoverable.
|
||||
type DirectedMatrix struct {
|
||||
mat *mat.Dense
|
||||
nodes []graph.Node
|
||||
|
||||
self float64
|
||||
absent float64
|
||||
}
|
||||
|
||||
// NewDirectedMatrix creates a directed dense graph with n nodes.
|
||||
// All edges are initialized with the weight given by init. The self parameter
|
||||
// specifies the cost of self connection, and absent specifies the weight
|
||||
// returned for absent edges.
|
||||
func NewDirectedMatrix(n int, init, self, absent float64) *DirectedMatrix {
|
||||
matrix := make([]float64, n*n)
|
||||
if init != 0 {
|
||||
for i := range matrix {
|
||||
matrix[i] = init
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(matrix); i += n + 1 {
|
||||
matrix[i] = self
|
||||
}
|
||||
return &DirectedMatrix{
|
||||
mat: mat.NewDense(n, n, matrix),
|
||||
self: self,
|
||||
absent: absent,
|
||||
}
|
||||
}
|
||||
|
||||
// NewDirectedMatrixFrom creates a directed dense graph with the given nodes.
|
||||
// The IDs of the nodes must be contiguous from 0 to len(nodes)-1, but may
|
||||
// be in any order. If IDs are not contiguous NewDirectedMatrixFrom will panic.
|
||||
// All edges are initialized with the weight given by init. The self parameter
|
||||
// specifies the cost of self connection, and absent specifies the weight
|
||||
// returned for absent edges.
|
||||
func NewDirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *DirectedMatrix {
|
||||
sort.Sort(ordered.ByID(nodes))
|
||||
for i, n := range nodes {
|
||||
if int64(i) != n.ID() {
|
||||
panic("simple: non-contiguous node IDs")
|
||||
}
|
||||
}
|
||||
g := NewDirectedMatrix(len(nodes), init, self, absent)
|
||||
g.nodes = nodes
|
||||
return g
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedMatrix) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdge(uid, vid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *DirectedMatrix) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
for j := 0; j < r; j++ {
|
||||
if i == j {
|
||||
continue
|
||||
}
|
||||
if w := g.mat.At(i, j); !isSame(w, g.absent) {
|
||||
edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *DirectedMatrix) From(id int64) graph.Nodes {
|
||||
if !g.has(id) {
|
||||
return graph.Empty
|
||||
}
|
||||
var nodes []graph.Node
|
||||
_, c := g.mat.Dims()
|
||||
for j := 0; j < c; j++ {
|
||||
if int64(j) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(int(id), j), g.absent) {
|
||||
nodes = append(nodes, g.Node(int64(j)))
|
||||
}
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *DirectedMatrix) HasEdgeBetween(xid, yid int64) bool {
|
||||
if !g.has(xid) {
|
||||
return false
|
||||
}
|
||||
if !g.has(yid) {
|
||||
return false
|
||||
}
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return xid != yid && (!isSame(g.mat.At(int(xid), int(yid)), g.absent) || !isSame(g.mat.At(int(yid), int(xid)), g.absent))
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *DirectedMatrix) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if !g.has(uid) {
|
||||
return false
|
||||
}
|
||||
if !g.has(vid) {
|
||||
return false
|
||||
}
|
||||
// uid and vid are not greater than maximum int by this point.
|
||||
return uid != vid && !isSame(g.mat.At(int(uid), int(vid)), g.absent)
|
||||
}
|
||||
|
||||
// Matrix returns the mat.Matrix representation of the graph. The orientation
|
||||
// of the matrix is such that the matrix entry at G_{ij} is the weight of the edge
|
||||
// from node i to node j.
|
||||
func (g *DirectedMatrix) Matrix() mat.Matrix {
|
||||
// Prevent alteration of dimensions of the returned matrix.
|
||||
m := *g.mat
|
||||
return &m
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *DirectedMatrix) Node(id int64) graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
}
|
||||
if g.nodes == nil {
|
||||
return Node(id)
|
||||
}
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *DirectedMatrix) Nodes() graph.Nodes {
|
||||
if g.nodes != nil {
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
copy(nodes, g.nodes)
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
r, _ := g.mat.Dims()
|
||||
// Matrix graphs must have at least one node.
|
||||
return iterator.NewImplicitNodes(0, r, newSimpleNode)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point nodes from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *DirectedMatrix) RemoveEdge(fid, tid int64) {
|
||||
if !g.has(fid) {
|
||||
return
|
||||
}
|
||||
if !g.has(tid) {
|
||||
return
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.Set(int(fid), int(tid), g.absent)
|
||||
}
|
||||
|
||||
// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge
|
||||
// are not in g or the edge is a self loop, SetEdge panics. SetEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewDirectedMatrixFrom.
|
||||
func (g *DirectedMatrix) SetEdge(e graph.Edge) {
|
||||
g.setWeightedEdge(e, 1)
|
||||
}
|
||||
|
||||
// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g
|
||||
// or the edge is a self loop, SetWeightedEdge panics. SetWeightedEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewDirectedMatrixFrom.
|
||||
func (g *DirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
g.setWeightedEdge(e, e.Weight())
|
||||
}
|
||||
|
||||
func (g *DirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) {
|
||||
from := e.From()
|
||||
fid := from.ID()
|
||||
to := e.To()
|
||||
tid := to.ID()
|
||||
if fid == tid {
|
||||
panic("simple: set illegal edge")
|
||||
}
|
||||
if int64(int(fid)) != fid {
|
||||
panic("simple: unavailable from node ID for dense graph")
|
||||
}
|
||||
if int64(int(tid)) != tid {
|
||||
panic("simple: unavailable to node ID for dense graph")
|
||||
}
|
||||
if g.nodes != nil {
|
||||
g.nodes[fid] = from
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.Set(int(fid), int(tid), weight)
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *DirectedMatrix) To(id int64) graph.Nodes {
|
||||
if !g.has(id) {
|
||||
return graph.Empty
|
||||
}
|
||||
var nodes []graph.Node
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
if int64(i) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(i, int(id)), g.absent) {
|
||||
nodes = append(nodes, g.Node(int64(i)))
|
||||
}
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *DirectedMatrix) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if g.HasEdgeFromTo(xid, yid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return g.mat.At(int(xid), int(yid)), true
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedMatrix) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
if g.HasEdgeFromTo(uid, vid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return WeightedEdge{F: g.Node(uid), T: g.Node(vid), W: g.mat.At(int(uid), int(vid))}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the edges in the graph.
|
||||
func (g *DirectedMatrix) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
for j := 0; j < r; j++ {
|
||||
if i == j {
|
||||
continue
|
||||
}
|
||||
if w := g.mat.At(i, j); !isSame(w, g.absent) {
|
||||
edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
||||
|
||||
func (g *DirectedMatrix) has(id int64) bool {
|
||||
r, _ := g.mat.Dims()
|
||||
return 0 <= id && id < int64(r)
|
||||
}
|
268
vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go
generated
vendored
Normal file
268
vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go
generated
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/ordered"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
var (
|
||||
um *UndirectedMatrix
|
||||
|
||||
_ graph.Graph = um
|
||||
_ graph.Undirected = um
|
||||
_ edgeSetter = um
|
||||
_ weightedEdgeSetter = um
|
||||
)
|
||||
|
||||
// UndirectedMatrix represents an undirected graph using an adjacency
|
||||
// matrix such that all IDs are in a contiguous block from 0 to n-1.
|
||||
// Edges are stored implicitly as an edge weight, so edges stored in
|
||||
// the graph are not recoverable.
|
||||
type UndirectedMatrix struct {
|
||||
mat *mat.SymDense
|
||||
nodes []graph.Node
|
||||
|
||||
self float64
|
||||
absent float64
|
||||
}
|
||||
|
||||
// NewUndirectedMatrix creates an undirected dense graph with n nodes.
|
||||
// All edges are initialized with the weight given by init. The self parameter
|
||||
// specifies the cost of self connection, and absent specifies the weight
|
||||
// returned for absent edges.
|
||||
func NewUndirectedMatrix(n int, init, self, absent float64) *UndirectedMatrix {
|
||||
matrix := make([]float64, n*n)
|
||||
if init != 0 {
|
||||
for i := range matrix {
|
||||
matrix[i] = init
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(matrix); i += n + 1 {
|
||||
matrix[i] = self
|
||||
}
|
||||
return &UndirectedMatrix{
|
||||
mat: mat.NewSymDense(n, matrix),
|
||||
self: self,
|
||||
absent: absent,
|
||||
}
|
||||
}
|
||||
|
||||
// NewUndirectedMatrixFrom creates an undirected dense graph with the given nodes.
|
||||
// The IDs of the nodes must be contiguous from 0 to len(nodes)-1, but may
|
||||
// be in any order. If IDs are not contiguous NewUndirectedMatrixFrom will panic.
|
||||
// All edges are initialized with the weight given by init. The self parameter
|
||||
// specifies the cost of self connection, and absent specifies the weight
|
||||
// returned for absent edges.
|
||||
func NewUndirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *UndirectedMatrix {
|
||||
sort.Sort(ordered.ByID(nodes))
|
||||
for i, n := range nodes {
|
||||
if int64(i) != n.ID() {
|
||||
panic("simple: non-contiguous node IDs")
|
||||
}
|
||||
}
|
||||
g := NewUndirectedMatrix(len(nodes), init, self, absent)
|
||||
g.nodes = nodes
|
||||
return g
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedMatrix) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *UndirectedMatrix) EdgeBetween(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *UndirectedMatrix) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
for j := i + 1; j < r; j++ {
|
||||
if w := g.mat.At(i, j); !isSame(w, g.absent) {
|
||||
edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *UndirectedMatrix) From(id int64) graph.Nodes {
|
||||
if !g.has(id) {
|
||||
return graph.Empty
|
||||
}
|
||||
var nodes []graph.Node
|
||||
r := g.mat.Symmetric()
|
||||
for i := 0; i < r; i++ {
|
||||
if int64(i) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(int(id), i), g.absent) {
|
||||
nodes = append(nodes, g.Node(int64(i)))
|
||||
}
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *UndirectedMatrix) HasEdgeBetween(uid, vid int64) bool {
|
||||
if !g.has(uid) {
|
||||
return false
|
||||
}
|
||||
if !g.has(vid) {
|
||||
return false
|
||||
}
|
||||
// uid and vid are not greater than maximum int by this point.
|
||||
return uid != vid && !isSame(g.mat.At(int(uid), int(vid)), g.absent)
|
||||
}
|
||||
|
||||
// Matrix returns the mat.Matrix representation of the graph.
|
||||
func (g *UndirectedMatrix) Matrix() mat.Matrix {
|
||||
// Prevent alteration of dimensions of the returned matrix.
|
||||
m := *g.mat
|
||||
return &m
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *UndirectedMatrix) Node(id int64) graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
}
|
||||
if g.nodes == nil {
|
||||
return Node(id)
|
||||
}
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *UndirectedMatrix) Nodes() graph.Nodes {
|
||||
if g.nodes != nil {
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
copy(nodes, g.nodes)
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
r := g.mat.Symmetric()
|
||||
// Matrix graphs must have at least one node.
|
||||
return iterator.NewImplicitNodes(0, r, newSimpleNode)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *UndirectedMatrix) RemoveEdge(fid, tid int64) {
|
||||
if !g.has(fid) {
|
||||
return
|
||||
}
|
||||
if !g.has(tid) {
|
||||
return
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.SetSym(int(fid), int(tid), g.absent)
|
||||
}
|
||||
|
||||
// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge are
|
||||
// not in g or the edge is a self loop, SetEdge panics. SetEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewUndirectedMatrixFrom.
|
||||
func (g *UndirectedMatrix) SetEdge(e graph.Edge) {
|
||||
g.setWeightedEdge(e, 1)
|
||||
}
|
||||
|
||||
// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g
|
||||
// or the edge is a self loop, SetWeightedEdge panics. SetWeightedEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewUndirectedMatrixFrom.
|
||||
func (g *UndirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
g.setWeightedEdge(e, e.Weight())
|
||||
}
|
||||
|
||||
func (g *UndirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) {
|
||||
from := e.From()
|
||||
fid := from.ID()
|
||||
to := e.To()
|
||||
tid := to.ID()
|
||||
if fid == tid {
|
||||
panic("simple: set illegal edge")
|
||||
}
|
||||
if int64(int(fid)) != fid {
|
||||
panic("simple: unavailable from node ID for dense graph")
|
||||
}
|
||||
if int64(int(tid)) != tid {
|
||||
panic("simple: unavailable to node ID for dense graph")
|
||||
}
|
||||
if g.nodes != nil {
|
||||
g.nodes[fid] = from
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.SetSym(int(fid), int(tid), weight)
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *UndirectedMatrix) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if g.HasEdgeBetween(xid, yid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return g.mat.At(int(xid), int(yid)), true
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedMatrix) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdgeBetween returns the weighted edge between nodes x and y.
|
||||
func (g *UndirectedMatrix) WeightedEdgeBetween(uid, vid int64) graph.WeightedEdge {
|
||||
if g.HasEdgeBetween(uid, vid) {
|
||||
// uid and vid are not greater than maximum int by this point.
|
||||
return WeightedEdge{F: g.Node(uid), T: g.Node(vid), W: g.mat.At(int(uid), int(vid))}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the edges in the graph.
|
||||
func (g *UndirectedMatrix) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
for j := i + 1; j < r; j++ {
|
||||
if w := g.mat.At(i, j); !isSame(w, g.absent) {
|
||||
edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
||||
|
||||
func (g *UndirectedMatrix) has(id int64) bool {
|
||||
r := g.mat.Symmetric()
|
||||
return 0 <= id && id < int64(r)
|
||||
}
|
235
vendor/gonum.org/v1/gonum/graph/simple/directed.go
generated
vendored
Normal file
235
vendor/gonum.org/v1/gonum/graph/simple/directed.go
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
dg *DirectedGraph
|
||||
|
||||
_ graph.Graph = dg
|
||||
_ graph.Directed = dg
|
||||
_ graph.NodeAdder = dg
|
||||
_ graph.NodeRemover = dg
|
||||
_ graph.EdgeAdder = dg
|
||||
_ graph.EdgeRemover = dg
|
||||
)
|
||||
|
||||
// DirectedGraph implements a generalized directed graph.
|
||||
type DirectedGraph struct {
|
||||
nodes map[int64]graph.Node
|
||||
from map[int64]map[int64]graph.Edge
|
||||
to map[int64]map[int64]graph.Edge
|
||||
|
||||
nodeIDs uid.Set
|
||||
}
|
||||
|
||||
// NewDirectedGraph returns a DirectedGraph.
|
||||
func NewDirectedGraph() *DirectedGraph {
|
||||
return &DirectedGraph{
|
||||
nodes: make(map[int64]graph.Node),
|
||||
from: make(map[int64]map[int64]graph.Edge),
|
||||
to: make(map[int64]map[int64]graph.Edge),
|
||||
|
||||
nodeIDs: uid.NewSet(),
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *DirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.from[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.to[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
edge, ok := g.from[uid][vid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *DirectedGraph) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *DirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
from := make([]graph.Node, len(g.from[id]))
|
||||
i := 0
|
||||
for vid := range g.from[id] {
|
||||
from[i] = g.nodes[vid]
|
||||
i++
|
||||
}
|
||||
if len(from) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(from)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *DirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
if _, ok := g.from[xid][yid]; ok {
|
||||
return true
|
||||
}
|
||||
_, ok := g.from[yid][xid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *DirectedGraph) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if _, ok := g.from[uid][vid]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NewEdge returns a new Edge from the source to the destination node.
|
||||
func (g *DirectedGraph) NewEdge(from, to graph.Node) graph.Edge {
|
||||
return &Edge{F: from, T: to}
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *DirectedGraph) NewNode() graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return Node(0)
|
||||
}
|
||||
if int64(len(g.nodes)) == uid.Max {
|
||||
panic("simple: cannot allocate node: no slot")
|
||||
}
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *DirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *DirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *DirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.from[fid], tid)
|
||||
delete(g.to[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
// to it. If the node is not in the graph it is a no-op.
|
||||
func (g *DirectedGraph) RemoveNode(id int64) {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return
|
||||
}
|
||||
delete(g.nodes, id)
|
||||
|
||||
for from := range g.from[id] {
|
||||
delete(g.to[from], id)
|
||||
}
|
||||
delete(g.from, id)
|
||||
|
||||
for to := range g.to[id] {
|
||||
delete(g.from[to], id)
|
||||
}
|
||||
delete(g.to, id)
|
||||
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *DirectedGraph) SetEdge(e graph.Edge) {
|
||||
var (
|
||||
from = e.From()
|
||||
fid = from.ID()
|
||||
to = e.To()
|
||||
tid = to.ID()
|
||||
)
|
||||
|
||||
if fid == tid {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.from[fid][tid] = e
|
||||
g.to[tid][fid] = e
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *DirectedGraph) To(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
to := make([]graph.Node, len(g.to[id]))
|
||||
i := 0
|
||||
for uid := range g.to[id] {
|
||||
to[i] = g.nodes[uid]
|
||||
i++
|
||||
}
|
||||
if len(to) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(to)
|
||||
}
|
9
vendor/gonum.org/v1/gonum/graph/simple/doc.go
generated
vendored
Normal file
9
vendor/gonum.org/v1/gonum/graph/simple/doc.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright ©2017 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 simple provides a suite of simple graph implementations satisfying
|
||||
// the gonum/graph interfaces.
|
||||
//
|
||||
// All types in simple return the graph.Empty value for empty iterators.
|
||||
package simple // import "gonum.org/v1/gonum/graph/simple"
|
72
vendor/gonum.org/v1/gonum/graph/simple/simple.go
generated
vendored
Normal file
72
vendor/gonum.org/v1/gonum/graph/simple/simple.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
)
|
||||
|
||||
// Node is a simple graph node.
|
||||
type Node int64
|
||||
|
||||
// ID returns the ID number of the node.
|
||||
func (n Node) ID() int64 {
|
||||
return int64(n)
|
||||
}
|
||||
|
||||
func newSimpleNode(id int) graph.Node {
|
||||
return Node(id)
|
||||
}
|
||||
|
||||
// Edge is a simple graph edge.
|
||||
type Edge struct {
|
||||
F, T graph.Node
|
||||
}
|
||||
|
||||
// From returns the from-node of the edge.
|
||||
func (e Edge) From() graph.Node { return e.F }
|
||||
|
||||
// To returns the to-node of the edge.
|
||||
func (e Edge) To() graph.Node { return e.T }
|
||||
|
||||
// ReversedLine returns a new Edge with the F and T fields
|
||||
// swapped.
|
||||
func (e Edge) ReversedEdge() graph.Edge { return Edge{F: e.T, T: e.F} }
|
||||
|
||||
// WeightedEdge is a simple weighted graph edge.
|
||||
type WeightedEdge struct {
|
||||
F, T graph.Node
|
||||
W float64
|
||||
}
|
||||
|
||||
// From returns the from-node of the edge.
|
||||
func (e WeightedEdge) From() graph.Node { return e.F }
|
||||
|
||||
// To returns the to-node of the edge.
|
||||
func (e WeightedEdge) To() graph.Node { return e.T }
|
||||
|
||||
// ReversedLine returns a new Edge with the F and T fields
|
||||
// swapped. The weight of the new Edge is the same as
|
||||
// the weight of the receiver.
|
||||
func (e WeightedEdge) ReversedEdge() graph.Edge { return WeightedEdge{F: e.T, T: e.F, W: e.W} }
|
||||
|
||||
// Weight returns the weight of the edge.
|
||||
func (e WeightedEdge) Weight() float64 { return e.W }
|
||||
|
||||
// isSame returns whether two float64 values are the same where NaN values
|
||||
// are equalable.
|
||||
func isSame(a, b float64) bool {
|
||||
return a == b || (math.IsNaN(a) && math.IsNaN(b))
|
||||
}
|
||||
|
||||
type edgeSetter interface {
|
||||
SetEdge(e graph.Edge)
|
||||
}
|
||||
|
||||
type weightedEdgeSetter interface {
|
||||
SetWeightedEdge(e graph.WeightedEdge)
|
||||
}
|
216
vendor/gonum.org/v1/gonum/graph/simple/undirected.go
generated
vendored
Normal file
216
vendor/gonum.org/v1/gonum/graph/simple/undirected.go
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
ug *UndirectedGraph
|
||||
|
||||
_ graph.Graph = ug
|
||||
_ graph.Undirected = ug
|
||||
_ graph.NodeAdder = ug
|
||||
_ graph.NodeRemover = ug
|
||||
_ graph.EdgeAdder = ug
|
||||
_ graph.EdgeRemover = ug
|
||||
)
|
||||
|
||||
// UndirectedGraph implements a generalized undirected graph.
|
||||
type UndirectedGraph struct {
|
||||
nodes map[int64]graph.Node
|
||||
edges map[int64]map[int64]graph.Edge
|
||||
|
||||
nodeIDs uid.Set
|
||||
}
|
||||
|
||||
// NewUndirectedGraph returns an UndirectedGraph.
|
||||
func NewUndirectedGraph() *UndirectedGraph {
|
||||
return &UndirectedGraph{
|
||||
nodes: make(map[int64]graph.Node),
|
||||
edges: make(map[int64]map[int64]graph.Edge),
|
||||
|
||||
nodeIDs: uid.NewSet(),
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *UndirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.edges[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.EdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *UndirectedGraph) EdgeBetween(xid, yid int64) graph.Edge {
|
||||
edge, ok := g.edges[xid][yid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if edge.From().ID() == xid {
|
||||
return edge
|
||||
}
|
||||
return edge.ReversedEdge()
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *UndirectedGraph) Edges() graph.Edges {
|
||||
if len(g.edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
var edges []graph.Edge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *UndirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
nodes := make([]graph.Node, len(g.edges[id]))
|
||||
i := 0
|
||||
for from := range g.edges[id] {
|
||||
nodes[i] = g.nodes[from]
|
||||
i++
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *UndirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
_, ok := g.edges[xid][yid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// NewEdge returns a new Edge from the source to the destination node.
|
||||
func (g *UndirectedGraph) NewEdge(from, to graph.Node) graph.Edge {
|
||||
return &Edge{F: from, T: to}
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *UndirectedGraph) NewNode() graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return Node(0)
|
||||
}
|
||||
if int64(len(g.nodes)) == uid.Max {
|
||||
panic("simple: cannot allocate node: no slot")
|
||||
}
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *UndirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *UndirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end IDs from the graph, leaving the terminal nodes.
|
||||
// If the edge does not exist it is a no-op.
|
||||
func (g *UndirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.edges[fid], tid)
|
||||
delete(g.edges[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
// to it. If the node is not in the graph it is a no-op.
|
||||
func (g *UndirectedGraph) RemoveNode(id int64) {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return
|
||||
}
|
||||
delete(g.nodes, id)
|
||||
|
||||
for from := range g.edges[id] {
|
||||
delete(g.edges[from], id)
|
||||
}
|
||||
delete(g.edges, id)
|
||||
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *UndirectedGraph) SetEdge(e graph.Edge) {
|
||||
var (
|
||||
from = e.From()
|
||||
fid = from.ID()
|
||||
to = e.To()
|
||||
tid = to.ID()
|
||||
)
|
||||
|
||||
if fid == tid {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.edges[fid][tid] = e
|
||||
g.edges[tid][fid] = e
|
||||
}
|
279
vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go
generated
vendored
Normal file
279
vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go
generated
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
wdg *WeightedDirectedGraph
|
||||
|
||||
_ graph.Graph = wdg
|
||||
_ graph.Weighted = wdg
|
||||
_ graph.Directed = wdg
|
||||
_ graph.WeightedDirected = wdg
|
||||
_ graph.NodeAdder = wdg
|
||||
_ graph.NodeRemover = wdg
|
||||
_ graph.WeightedEdgeAdder = wdg
|
||||
_ graph.EdgeRemover = wdg
|
||||
)
|
||||
|
||||
// WeightedDirectedGraph implements a generalized weighted directed graph.
|
||||
type WeightedDirectedGraph struct {
|
||||
nodes map[int64]graph.Node
|
||||
from map[int64]map[int64]graph.WeightedEdge
|
||||
to map[int64]map[int64]graph.WeightedEdge
|
||||
|
||||
self, absent float64
|
||||
|
||||
nodeIDs uid.Set
|
||||
}
|
||||
|
||||
// NewWeightedDirectedGraph returns a WeightedDirectedGraph with the specified self and absent
|
||||
// edge weight values.
|
||||
func NewWeightedDirectedGraph(self, absent float64) *WeightedDirectedGraph {
|
||||
return &WeightedDirectedGraph{
|
||||
nodes: make(map[int64]graph.Node),
|
||||
from: make(map[int64]map[int64]graph.WeightedEdge),
|
||||
to: make(map[int64]map[int64]graph.WeightedEdge),
|
||||
|
||||
self: self,
|
||||
absent: absent,
|
||||
|
||||
nodeIDs: uid.NewSet(),
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *WeightedDirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.from[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.to[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedDirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdge(uid, vid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *WeightedDirectedGraph) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *WeightedDirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
from := make([]graph.Node, len(g.from[id]))
|
||||
i := 0
|
||||
for vid := range g.from[id] {
|
||||
from[i] = g.nodes[vid]
|
||||
i++
|
||||
}
|
||||
if len(from) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(from)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *WeightedDirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
if _, ok := g.from[xid][yid]; ok {
|
||||
return true
|
||||
}
|
||||
_, ok := g.from[yid][xid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *WeightedDirectedGraph) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if _, ok := g.from[uid][vid]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *WeightedDirectedGraph) NewNode() graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return Node(0)
|
||||
}
|
||||
if int64(len(g.nodes)) == uid.Max {
|
||||
panic("simple: cannot allocate node: no slot")
|
||||
}
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// NewWeightedEdge returns a new weighted edge from the source to the destination node.
|
||||
func (g *WeightedDirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge {
|
||||
return &WeightedEdge{F: from, T: to, W: weight}
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *WeightedDirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *WeightedDirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.from) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *WeightedDirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.from[fid], tid)
|
||||
delete(g.to[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
// to it. If the node is not in the graph it is a no-op.
|
||||
func (g *WeightedDirectedGraph) RemoveNode(id int64) {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return
|
||||
}
|
||||
delete(g.nodes, id)
|
||||
|
||||
for from := range g.from[id] {
|
||||
delete(g.to[from], id)
|
||||
}
|
||||
delete(g.from, id)
|
||||
|
||||
for to := range g.to[id] {
|
||||
delete(g.from[to], id)
|
||||
}
|
||||
delete(g.to, id)
|
||||
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *WeightedDirectedGraph) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
var (
|
||||
from = e.From()
|
||||
fid = from.ID()
|
||||
to = e.To()
|
||||
tid = to.ID()
|
||||
)
|
||||
|
||||
if fid == tid {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.from[fid][tid] = e
|
||||
g.to[tid][fid] = e
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *WeightedDirectedGraph) To(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
to := make([]graph.Node, len(g.to[id]))
|
||||
i := 0
|
||||
for uid := range g.to[id] {
|
||||
to[i] = g.nodes[uid]
|
||||
i++
|
||||
}
|
||||
if len(to) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(to)
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *WeightedDirectedGraph) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if to, ok := g.from[xid]; ok {
|
||||
if e, ok := to[yid]; ok {
|
||||
return e.Weight(), true
|
||||
}
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedDirectedGraph) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
edge, ok := g.from[uid][vid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the weighted edges in the graph.
|
||||
func (g *WeightedDirectedGraph) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
273
vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go
generated
vendored
Normal file
273
vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go
generated
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
// Copyright ©2014 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 simple
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
wug *WeightedUndirectedGraph
|
||||
|
||||
_ graph.Graph = wug
|
||||
_ graph.Weighted = wug
|
||||
_ graph.Undirected = wug
|
||||
_ graph.WeightedUndirected = wug
|
||||
_ graph.NodeAdder = wug
|
||||
_ graph.NodeRemover = wug
|
||||
_ graph.WeightedEdgeAdder = wug
|
||||
_ graph.EdgeRemover = wug
|
||||
)
|
||||
|
||||
// WeightedUndirectedGraph implements a generalized weighted undirected graph.
|
||||
type WeightedUndirectedGraph struct {
|
||||
nodes map[int64]graph.Node
|
||||
edges map[int64]map[int64]graph.WeightedEdge
|
||||
|
||||
self, absent float64
|
||||
|
||||
nodeIDs uid.Set
|
||||
}
|
||||
|
||||
// NewWeightedUndirectedGraph returns an WeightedUndirectedGraph with the specified self and absent
|
||||
// edge weight values.
|
||||
func NewWeightedUndirectedGraph(self, absent float64) *WeightedUndirectedGraph {
|
||||
return &WeightedUndirectedGraph{
|
||||
nodes: make(map[int64]graph.Node),
|
||||
edges: make(map[int64]map[int64]graph.WeightedEdge),
|
||||
|
||||
self: self,
|
||||
absent: absent,
|
||||
|
||||
nodeIDs: uid.NewSet(),
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *WeightedUndirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.edges[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedUndirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) EdgeBetween(xid, yid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(xid, yid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *WeightedUndirectedGraph) Edges() graph.Edges {
|
||||
if len(g.edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
var edges []graph.Edge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *WeightedUndirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
nodes := make([]graph.Node, len(g.edges[id]))
|
||||
i := 0
|
||||
for from := range g.edges[id] {
|
||||
nodes[i] = g.nodes[from]
|
||||
i++
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
_, ok := g.edges[xid][yid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *WeightedUndirectedGraph) NewNode() graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return Node(0)
|
||||
}
|
||||
if int64(len(g.nodes)) == uid.Max {
|
||||
panic("simple: cannot allocate node: no slot")
|
||||
}
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// NewWeightedEdge returns a new weighted edge from the source to the destination node.
|
||||
func (g *WeightedUndirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge {
|
||||
return &WeightedEdge{F: from, T: to, W: weight}
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *WeightedUndirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *WeightedUndirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *WeightedUndirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.edges[fid], tid)
|
||||
delete(g.edges[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
// to it. If the node is not in the graph it is a no-op.
|
||||
func (g *WeightedUndirectedGraph) RemoveNode(id int64) {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return
|
||||
}
|
||||
delete(g.nodes, id)
|
||||
|
||||
for from := range g.edges[id] {
|
||||
delete(g.edges[from], id)
|
||||
}
|
||||
delete(g.edges, id)
|
||||
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *WeightedUndirectedGraph) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
var (
|
||||
from = e.From()
|
||||
fid = from.ID()
|
||||
to = e.To()
|
||||
tid = to.ID()
|
||||
)
|
||||
|
||||
if fid == tid {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.edges[fid][tid] = e
|
||||
g.edges[tid][fid] = e
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *WeightedUndirectedGraph) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if n, ok := g.edges[xid]; ok {
|
||||
if e, ok := n[yid]; ok {
|
||||
return e.Weight(), true
|
||||
}
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdgeBetween returns the weighted edge between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdgeBetween(xid, yid int64) graph.WeightedEdge {
|
||||
edge, ok := g.edges[xid][yid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if edge.From().ID() == xid {
|
||||
return edge
|
||||
}
|
||||
return edge.ReversedEdge().(graph.WeightedEdge)
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the weighted edges in the graph.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
Reference in New Issue
Block a user