// Copyright ©2018 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 testgraph import ( "math" "gonum.org/v1/gonum/graph" ) // node is a graph.Node implementation that is not exported // so that other packages will not be aware of its implementation. type node int64 func (n node) ID() int64 { return int64(n) } // line is an extended graph.Edge implementation that is not exported // so that other packages will not be aware of its implementation. It // covers all the edge types exported by graph. type line struct { F, T graph.Node UID int64 W float64 } func (e line) From() graph.Node { return e.F } func (e line) To() graph.Node { return e.T } func (e line) ReversedEdge() graph.Edge { e.F, e.T = e.T, e.F; return e } func (e line) ID() int64 { return e.UID } func (e line) Weight() float64 { return e.W } var testCases = []struct { // name is the name of the test. name string // nodes is the set of nodes that should be used // to construct the graph. nodes []graph.Node // edges is the set of edges that should be used // to construct the graph. edges []WeightedLine // nonexist is a set of nodes that should not be // found within the graph. nonexist []graph.Node // self is the weight value associated with // a self edge for simple graphs that do not // store individual self edges. self float64 // absent is the weight value associated // with absent edges. absent float64 }{ { name: "empty", nonexist: []graph.Node{node(-1), node(0), node(1)}, self: 0, absent: math.Inf(1), }, { name: "one - negative", nodes: []graph.Node{node(-1)}, nonexist: []graph.Node{node(0), node(1)}, self: 0, absent: math.Inf(1), }, { name: "one - zero", nodes: []graph.Node{node(0)}, nonexist: []graph.Node{node(-1), node(1)}, self: 0, absent: math.Inf(1), }, { name: "one - positive", nodes: []graph.Node{node(1)}, nonexist: []graph.Node{node(-1), node(0)}, self: 0, absent: math.Inf(1), }, { name: "one - self loop", nodes: []graph.Node{node(0)}, edges: []WeightedLine{line{F: node(0), T: node(0), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(-1), node(1)}, self: 0, absent: math.Inf(1), }, { name: "two - positive", nodes: []graph.Node{node(1), node(2)}, edges: []WeightedLine{line{F: node(1), T: node(2), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(-1), node(0)}, self: 0, absent: math.Inf(1), }, { name: "two - negative", nodes: []graph.Node{node(-1), node(-2)}, edges: []WeightedLine{line{F: node(-1), T: node(-2), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(0), node(-3)}, self: 0, absent: math.Inf(1), }, { name: "two - zero spanning", nodes: []graph.Node{node(-1), node(1)}, edges: []WeightedLine{line{F: node(-1), T: node(1), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(0), node(2)}, self: 0, absent: math.Inf(1), }, { name: "two - zero contiguous", nodes: []graph.Node{node(0), node(1)}, edges: []WeightedLine{line{F: node(0), T: node(1), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(-1), node(2)}, self: 0, absent: math.Inf(1), }, { name: "three - positive", nodes: []graph.Node{node(1), node(2), node(3)}, edges: []WeightedLine{line{F: node(1), T: node(2), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(-1), node(0)}, self: 0, absent: math.Inf(1), }, { name: "three - negative", nodes: []graph.Node{node(-1), node(-2), node(-3)}, edges: []WeightedLine{line{F: node(-1), T: node(-2), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(0), node(1)}, self: 0, absent: math.Inf(1), }, { name: "three - zero spanning", nodes: []graph.Node{node(-1), node(0), node(1)}, edges: []WeightedLine{line{F: node(-1), T: node(1), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(-2), node(2)}, self: 0, absent: math.Inf(1), }, { name: "three - zero contiguous", nodes: []graph.Node{node(0), node(1), node(2)}, edges: []WeightedLine{line{F: node(0), T: node(1), UID: 0, W: 0.5}}, nonexist: []graph.Node{node(-1), node(3)}, self: 0, absent: math.Inf(1), }, { name: "three in only", nodes: []graph.Node{node(0), node(1), node(2), node(3)}, edges: []WeightedLine{ line{F: node(1), T: node(0), UID: 0, W: 0.5}, line{F: node(2), T: node(0), UID: 1, W: 0.5}, line{F: node(3), T: node(0), UID: 2, W: 0.5}, }, nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "three out only", nodes: []graph.Node{node(0), node(1), node(2), node(3)}, edges: []WeightedLine{ line{F: node(0), T: node(1), UID: 0, W: 0.5}, line{F: node(0), T: node(2), UID: 1, W: 0.5}, line{F: node(0), T: node(3), UID: 2, W: 0.5}, }, nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique - single(non-prepared)", edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i + 1; j < 4; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique+ - single(non-prepared)", edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i; j < 4; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique - single(prepared)", nodes: func() []graph.Node { const n = 4 nodes := make([]graph.Node, n) for i := range nodes { nodes[i] = node(i) } return nodes }(), edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i + 1; j < n; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique+ - single(prepared)", nodes: func() []graph.Node { const n = 4 nodes := make([]graph.Node, n) for i := range nodes { nodes[i] = node(i) } return nodes }(), edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i; j < n; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique - double(non-prepared)", edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i + 1; j < n; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ edges = append(edges, line{F: node(j), T: node(i), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique+ - double(non-prepared)", edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i; j < n; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ edges = append(edges, line{F: node(j), T: node(i), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique - double(prepared)", nodes: func() []graph.Node { const n = 4 nodes := make([]graph.Node, n) for i := range nodes { nodes[i] = node(i) } return nodes }(), edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i + 1; j < n; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ edges = append(edges, line{F: node(j), T: node(i), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "4-clique+ - double(prepared)", nodes: func() []graph.Node { const n = 4 nodes := make([]graph.Node, n) for i := range nodes { nodes[i] = node(i) } return nodes }(), edges: func() []WeightedLine { const n = 4 var uid int64 var edges []WeightedLine for i := 0; i < n; i++ { for j := i; j < n; j++ { edges = append(edges, line{F: node(i), T: node(j), UID: uid, W: 0.5}) uid++ edges = append(edges, line{F: node(j), T: node(i), UID: uid, W: 0.5}) uid++ } } return edges }(), nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, { name: "issue 1686", nodes: []graph.Node{node(0), node(1), node(2)}, edges: []WeightedLine{ line{F: node(0), T: node(1), UID: 0, W: 0.5}, line{F: node(1), T: node(2), UID: 0, W: 0.5}, }, nonexist: []graph.Node{node(-1), node(4)}, self: 0, absent: math.Inf(1), }, }