mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +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:
		
							
								
								
									
										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( | go_test( | ||||||
|     name = "go_default_test", |     name = "go_default_test", | ||||||
|     srcs = ["undirected_test.go"], |     srcs = [ | ||||||
|  |         "directed_acyclic_test.go", | ||||||
|  |         "undirected_test.go", | ||||||
|  |     ], | ||||||
|     library = ":go_default_library", |     library = ":go_default_library", | ||||||
|     tags = ["automanaged"], |     tags = ["automanaged"], | ||||||
|     deps = ["//third_party/forked/gonum/graph:go_default_library"], |     deps = ["//third_party/forked/gonum/graph:go_default_library"], | ||||||
| @@ -19,6 +22,7 @@ go_test( | |||||||
| go_library( | go_library( | ||||||
|     name = "go_default_library", |     name = "go_default_library", | ||||||
|     srcs = [ |     srcs = [ | ||||||
|  |         "directed_acyclic.go", | ||||||
|         "simple.go", |         "simple.go", | ||||||
|         "undirected.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) | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user