mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-30 21:30:16 +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( | ||||
|     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) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user