gonum.org/v1/gonum@v0.14.0/graph/simple/undirected_test.go (about)

     1  // Copyright ©2014 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package simple_test
     6  
     7  import (
     8  	"math"
     9  	"testing"
    10  
    11  	"golang.org/x/exp/rand"
    12  
    13  	"gonum.org/v1/gonum/graph"
    14  	"gonum.org/v1/gonum/graph/internal/set"
    15  	"gonum.org/v1/gonum/graph/simple"
    16  	"gonum.org/v1/gonum/graph/testgraph"
    17  )
    18  
    19  const (
    20  	usesEmpty     = true
    21  	reversesEdges = true
    22  )
    23  
    24  func undirectedBuilder(nodes []graph.Node, edges []testgraph.WeightedLine, _, _ float64) (g graph.Graph, n []graph.Node, e []testgraph.Edge, s, a float64, ok bool) {
    25  	seen := set.NewNodes()
    26  	ug := simple.NewUndirectedGraph()
    27  	for _, n := range nodes {
    28  		seen.Add(n)
    29  		ug.AddNode(n)
    30  	}
    31  	for _, edge := range edges {
    32  		if edge.From().ID() == edge.To().ID() {
    33  			continue
    34  		}
    35  		f := ug.Node(edge.From().ID())
    36  		if f == nil {
    37  			f = edge.From()
    38  		}
    39  		t := ug.Node(edge.To().ID())
    40  		if t == nil {
    41  			t = edge.To()
    42  		}
    43  		ce := simple.Edge{F: f, T: t}
    44  		seen.Add(ce.F)
    45  		seen.Add(ce.T)
    46  		e = append(e, ce)
    47  		ug.SetEdge(ce)
    48  	}
    49  	if len(e) == 0 && len(edges) != 0 {
    50  		return nil, nil, nil, math.NaN(), math.NaN(), false
    51  	}
    52  	if len(seen) != 0 {
    53  		n = make([]graph.Node, 0, len(seen))
    54  	}
    55  	for _, sn := range seen {
    56  		n = append(n, sn)
    57  	}
    58  	return ug, n, e, math.NaN(), math.NaN(), true
    59  }
    60  
    61  func TestUndirected(t *testing.T) {
    62  	t.Run("EdgeExistence", func(t *testing.T) {
    63  		testgraph.EdgeExistence(t, undirectedBuilder, reversesEdges)
    64  	})
    65  	t.Run("NodeExistence", func(t *testing.T) {
    66  		testgraph.NodeExistence(t, undirectedBuilder)
    67  	})
    68  	t.Run("ReturnAdjacentNodes", func(t *testing.T) {
    69  		testgraph.ReturnAdjacentNodes(t, undirectedBuilder, usesEmpty, reversesEdges)
    70  	})
    71  	t.Run("ReturnAllEdges", func(t *testing.T) {
    72  		testgraph.ReturnAllEdges(t, undirectedBuilder, usesEmpty)
    73  	})
    74  	t.Run("ReturnAllNodes", func(t *testing.T) {
    75  		testgraph.ReturnAllNodes(t, undirectedBuilder, usesEmpty)
    76  	})
    77  	t.Run("ReturnEdgeSlice", func(t *testing.T) {
    78  		testgraph.ReturnEdgeSlice(t, undirectedBuilder, usesEmpty)
    79  	})
    80  	t.Run("ReturnNodeSlice", func(t *testing.T) {
    81  		testgraph.ReturnNodeSlice(t, undirectedBuilder, usesEmpty)
    82  	})
    83  
    84  	t.Run("AddNodes", func(t *testing.T) {
    85  		testgraph.AddNodes(t, simple.NewUndirectedGraph(), 100)
    86  	})
    87  	t.Run("AddArbitraryNodes", func(t *testing.T) {
    88  		testgraph.AddArbitraryNodes(t,
    89  			simple.NewUndirectedGraph(),
    90  			testgraph.NewRandomNodes(100, 1, func(id int64) graph.Node { return simple.Node(id) }),
    91  		)
    92  	})
    93  	t.Run("RemoveNodes", func(t *testing.T) {
    94  		g := simple.NewUndirectedGraph()
    95  		it := testgraph.NewRandomNodes(100, 1, func(id int64) graph.Node { return simple.Node(id) })
    96  		for it.Next() {
    97  			g.AddNode(it.Node())
    98  		}
    99  		it.Reset()
   100  		rnd := rand.New(rand.NewSource(1))
   101  		for it.Next() {
   102  			u := it.Node()
   103  			d := rnd.Intn(5)
   104  			vit := g.Nodes()
   105  			for d >= 0 && vit.Next() {
   106  				v := vit.Node()
   107  				if v.ID() == u.ID() {
   108  					continue
   109  				}
   110  				d--
   111  				g.SetEdge(g.NewEdge(u, v))
   112  			}
   113  		}
   114  		testgraph.RemoveNodes(t, g)
   115  	})
   116  	t.Run("AddEdges", func(t *testing.T) {
   117  		testgraph.AddEdges(t, 100,
   118  			simple.NewUndirectedGraph(),
   119  			func(id int64) graph.Node { return simple.Node(id) },
   120  			false, // Cannot set self-loops.
   121  			true,  // Can update nodes.
   122  		)
   123  	})
   124  	t.Run("NoLoopAddEdges", func(t *testing.T) {
   125  		testgraph.NoLoopAddEdges(t, 100,
   126  			simple.NewUndirectedGraph(),
   127  			func(id int64) graph.Node { return simple.Node(id) },
   128  		)
   129  	})
   130  	t.Run("RemoveEdges", func(t *testing.T) {
   131  		g := simple.NewUndirectedGraph()
   132  		it := testgraph.NewRandomNodes(100, 1, func(id int64) graph.Node { return simple.Node(id) })
   133  		for it.Next() {
   134  			g.AddNode(it.Node())
   135  		}
   136  		it.Reset()
   137  		rnd := rand.New(rand.NewSource(1))
   138  		for it.Next() {
   139  			u := it.Node()
   140  			d := rnd.Intn(5)
   141  			vit := g.Nodes()
   142  			for d >= 0 && vit.Next() {
   143  				v := vit.Node()
   144  				if v.ID() == u.ID() {
   145  					continue
   146  				}
   147  				d--
   148  				g.SetEdge(g.NewEdge(u, v))
   149  			}
   150  		}
   151  		testgraph.RemoveEdges(t, g, g.Edges())
   152  	})
   153  }
   154  
   155  func TestAssertMutableNotDirected(t *testing.T) {
   156  	var g graph.UndirectedBuilder = simple.NewUndirectedGraph()
   157  	if _, ok := g.(graph.Directed); ok {
   158  		t.Fatal("Graph is directed, but a MutableGraph cannot safely be directed!")
   159  	}
   160  }
   161  
   162  func TestMaxID(t *testing.T) {
   163  	g := simple.NewUndirectedGraph()
   164  	nodes := make(map[graph.Node]struct{})
   165  	for i := simple.Node(0); i < 3; i++ {
   166  		g.AddNode(i)
   167  		nodes[i] = struct{}{}
   168  	}
   169  	g.RemoveNode(int64(0))
   170  	delete(nodes, simple.Node(0))
   171  	g.RemoveNode(int64(2))
   172  	delete(nodes, simple.Node(2))
   173  	n := g.NewNode()
   174  	g.AddNode(n)
   175  	if g.Node(n.ID()) == nil {
   176  		t.Error("added node does not exist in graph")
   177  	}
   178  	if _, exists := nodes[n]; exists {
   179  		t.Errorf("Created already existing node id: %v", n.ID())
   180  	}
   181  }
   182  
   183  // Test for issue #123 https://github.com/gonum/graph/issues/123
   184  func TestIssue123UndirectedGraph(t *testing.T) {
   185  	defer func() {
   186  		if r := recover(); r != nil {
   187  			t.Errorf("unexpected panic: %v", r)
   188  		}
   189  	}()
   190  	g := simple.NewUndirectedGraph()
   191  
   192  	n0 := g.NewNode()
   193  	g.AddNode(n0)
   194  
   195  	n1 := g.NewNode()
   196  	g.AddNode(n1)
   197  
   198  	g.RemoveNode(n0.ID())
   199  
   200  	n2 := g.NewNode()
   201  	g.AddNode(n2)
   202  }