mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
gonum: directed acyclic graph
Implements graph.Directed capable of storing at most one edge between any two nodes. Uses the Undirected implementation for space efficiency (~30% space savings).
This commit is contained in:
parent
b1ac314046
commit
ec1d79da19
6
third_party/forked/gonum/graph/simple/BUILD
vendored
6
third_party/forked/gonum/graph/simple/BUILD
vendored
@ -10,7 +10,10 @@ load(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["undirected_test.go"],
|
||||
srcs = [
|
||||
"directed_acyclic_test.go",
|
||||
"undirected_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = ["//third_party/forked/gonum/graph:go_default_library"],
|
||||
@ -19,6 +22,7 @@ go_test(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"directed_acyclic.go",
|
||||
"simple.go",
|
||||
"undirected.go",
|
||||
],
|
||||
|
55
third_party/forked/gonum/graph/simple/directed_acyclic.go
vendored
Normal file
55
third_party/forked/gonum/graph/simple/directed_acyclic.go
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package simple
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/third_party/forked/gonum/graph"
|
||||
)
|
||||
|
||||
// DirectedAcyclicGraph implements graph.Directed using UndirectedGraph,
|
||||
// which only stores one edge for any node pair.
|
||||
type DirectedAcyclicGraph struct {
|
||||
*UndirectedGraph
|
||||
}
|
||||
|
||||
func NewDirectedAcyclicGraph(self, absent float64) *DirectedAcyclicGraph {
|
||||
return &DirectedAcyclicGraph{
|
||||
UndirectedGraph: NewUndirectedGraph(self, absent),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *DirectedAcyclicGraph) HasEdgeFromTo(u, v graph.Node) bool {
|
||||
edge := g.UndirectedGraph.EdgeBetween(u, v)
|
||||
if edge == nil {
|
||||
return false
|
||||
}
|
||||
return (edge.From().ID() == u.ID())
|
||||
}
|
||||
|
||||
func (g *DirectedAcyclicGraph) From(n graph.Node) []graph.Node {
|
||||
if !g.Has(n) {
|
||||
return nil
|
||||
}
|
||||
|
||||
fid := n.ID()
|
||||
nodes := make([]graph.Node, 0, len(g.UndirectedGraph.edges[n.ID()]))
|
||||
for _, edge := range g.UndirectedGraph.edges[n.ID()] {
|
||||
if edge.From().ID() == fid {
|
||||
nodes = append(nodes, g.UndirectedGraph.nodes[edge.To().ID()])
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (g *DirectedAcyclicGraph) To(n graph.Node) []graph.Node {
|
||||
if !g.Has(n) {
|
||||
return nil
|
||||
}
|
||||
|
||||
tid := n.ID()
|
||||
nodes := make([]graph.Node, 0, len(g.UndirectedGraph.edges[n.ID()]))
|
||||
for _, edge := range g.UndirectedGraph.edges[n.ID()] {
|
||||
if edge.To().ID() == tid {
|
||||
nodes = append(nodes, g.UndirectedGraph.nodes[edge.From().ID()])
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
62
third_party/forked/gonum/graph/simple/directed_acyclic_test.go
vendored
Normal file
62
third_party/forked/gonum/graph/simple/directed_acyclic_test.go
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
// 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"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/third_party/forked/gonum/graph"
|
||||
)
|
||||
|
||||
var _ graph.Graph = &DirectedAcyclicGraph{}
|
||||
var _ graph.Directed = &DirectedAcyclicGraph{}
|
||||
|
||||
// Tests Issue #27
|
||||
func TestAcyclicEdgeOvercounting(t *testing.T) {
|
||||
g := generateDummyAcyclicGraph()
|
||||
|
||||
if neigh := g.From(Node(Node(2))); len(neigh) != 2 {
|
||||
t.Errorf("Node 2 has incorrect number of neighbors got neighbors %v (count %d), expected 2 neighbors {0,1}", neigh, len(neigh))
|
||||
}
|
||||
}
|
||||
|
||||
func generateDummyAcyclicGraph() *DirectedAcyclicGraph {
|
||||
nodes := [4]struct{ srcID, targetID int }{
|
||||
{2, 1},
|
||||
{1, 0},
|
||||
{0, 2},
|
||||
{2, 0},
|
||||
}
|
||||
|
||||
g := NewDirectedAcyclicGraph(0, math.Inf(1))
|
||||
|
||||
for _, n := range nodes {
|
||||
g.SetEdge(Edge{F: Node(n.srcID), T: Node(n.targetID), W: 1})
|
||||
}
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
// Test for issue #123 https://github.com/gonum/graph/issues/123
|
||||
func TestAcyclicIssue123DirectedGraph(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("unexpected panic: %v", r)
|
||||
}
|
||||
}()
|
||||
g := NewDirectedAcyclicGraph(0, math.Inf(1))
|
||||
|
||||
n0 := Node(g.NewNodeID())
|
||||
g.AddNode(n0)
|
||||
|
||||
n1 := Node(g.NewNodeID())
|
||||
g.AddNode(n1)
|
||||
|
||||
g.RemoveNode(n0)
|
||||
|
||||
n2 := Node(g.NewNodeID())
|
||||
g.AddNode(n2)
|
||||
}
|
Loading…
Reference in New Issue
Block a user