fixed dependencies

This commit is contained in:
nuknal
2024-10-24 15:46:01 +08:00
parent d16a5bd9c0
commit 1161e8d054
2005 changed files with 690883 additions and 0 deletions

279
vendor/gonum.org/v1/plot/plotter/johnson.go generated vendored Normal file
View File

@@ -0,0 +1,279 @@
// Copyright ©2015 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 plotter
// johnson implements Johnson's "Finding all the elementary
// circuits of a directed graph" algorithm. SIAM J. Comput. 4(1):1975.
//
// Comments in the johnson methods are kept in sync with the comments
// and labels from the paper.
type johnson struct {
adjacent graph // SCC adjacency list.
b []set // Johnson's "B-list".
blocked []bool
s int
stack []int
result [][]int
}
// cyclesIn returns the set of elementary cycles in the graph g.
func cyclesIn(g graph) [][]int {
j := johnson{
adjacent: g.clone(),
b: make([]set, len(g)),
blocked: make([]bool, len(g)),
}
// len(j.adjacent) will be the order of g until Tarjan's analysis
// finds no SCC, at which point t.sccSubGraph returns nil and the
// loop breaks.
for j.s < len(j.adjacent)-1 {
// We use the previous SCC adjacency to reduce the work needed.
t := newTarjan(j.adjacent.subgraph(j.s))
// A_k = adjacency structure of strong component K with least
// vertex in subgraph of G induced by {s, s+1, ... ,n}.
j.adjacent = t.sccSubGraph(2) // Only allow SCCs with >= 2 vertices.
if len(j.adjacent) == 0 {
break
}
// s = least vertex in V_k
for _, v := range j.adjacent {
s := len(j.adjacent)
for n := range v {
if n < s {
s = n
}
}
if s < j.s {
j.s = s
}
}
for i, v := range j.adjacent {
if len(v) > 0 {
j.blocked[i] = false
j.b[i] = make(set)
}
}
//L3:
_ = j.circuit(j.s)
j.s++
}
return j.result
}
// circuit is the CIRCUIT sub-procedure in the paper.
func (j *johnson) circuit(v int) bool {
f := false
j.stack = append(j.stack, v)
j.blocked[v] = true
//L1:
for w := range j.adjacent[v] {
if w == j.s {
// Output circuit composed of stack followed by s.
r := make([]int, len(j.stack)+1)
copy(r, j.stack)
r[len(r)-1] = j.s
j.result = append(j.result, r)
f = true
} else if !j.blocked[w] {
if j.circuit(w) {
f = true
}
}
}
//L2:
if f {
j.unblock(v)
} else {
for w := range j.adjacent[v] {
j.b[w][v] = struct{}{}
}
}
j.stack = j.stack[:len(j.stack)-1]
return f
}
// unblock is the UNBLOCK sub-procedure in the paper.
func (j *johnson) unblock(u int) {
j.blocked[u] = false
for w := range j.b[u] {
delete(j.b[u], w)
if j.blocked[w] {
j.unblock(w)
}
}
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
// tarjan implements Tarjan's strongly connected component finding
// algorithm. The implementation is from the pseudocode at
//
// http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm?oldid=642744644
type tarjan struct {
g graph
index int
indexTable []int
lowLink []int
onStack []bool
stack []int
sccs [][]int
}
// newTarjan returns a tarjan with the sccs field filled with the
// strongly connected components of the directed graph g.
func newTarjan(g graph) *tarjan {
t := tarjan{
g: g,
indexTable: make([]int, len(g)),
lowLink: make([]int, len(g)),
onStack: make([]bool, len(g)),
}
for v := range t.g {
if t.indexTable[v] == 0 {
t.strongconnect(v)
}
}
return &t
}
// strongconnect is the strongconnect function described in the
// wikipedia article.
func (t *tarjan) strongconnect(v int) {
// Set the depth index for v to the smallest unused index.
t.index++
t.indexTable[v] = t.index
t.lowLink[v] = t.index
t.stack = append(t.stack, v)
t.onStack[v] = true
// Consider successors of v.
for w := range t.g[v] {
if t.indexTable[w] == 0 {
// Successor w has not yet been visited; recur on it.
t.strongconnect(w)
t.lowLink[v] = min(t.lowLink[v], t.lowLink[w])
} else if t.onStack[w] {
// Successor w is in stack s and hence in the current SCC.
t.lowLink[v] = min(t.lowLink[v], t.indexTable[w])
}
}
// If v is a root node, pop the stack and generate an SCC.
if t.lowLink[v] == t.indexTable[v] {
// Start a new strongly connected component.
var (
scc []int
w int
)
for {
w, t.stack = t.stack[len(t.stack)-1], t.stack[:len(t.stack)-1]
t.onStack[w] = false
// Add w to current strongly connected component.
scc = append(scc, w)
if w == v {
break
}
}
// Output the current strongly connected component.
t.sccs = append(t.sccs, scc)
}
}
// sccSubGraph returns the graph of the tarjan's strongly connected
// components with each SCC containing at least min vertices.
// sccSubGraph returns nil if there is no SCC with at least min
// members.
func (t *tarjan) sccSubGraph(min int) graph {
if len(t.g) == 0 {
return nil
}
sub := make(graph, len(t.g))
var n int
for _, scc := range t.sccs {
if len(scc) < min {
continue
}
n++
for _, u := range scc {
for _, v := range scc {
if _, ok := t.g[u][v]; ok {
if sub[u] == nil {
sub[u] = make(set)
}
sub[u][v] = struct{}{}
}
}
}
}
if n == 0 {
return nil
}
return sub
}
// set is an integer set.
type set map[int]struct{}
// graph is an edge list representation of a graph.
type graph []set
// remove deletes edges that make up the given paths from the graph.
func (g graph) remove(paths [][]int) {
for _, p := range paths {
for i, u := range p[:len(p)-1] {
delete(g[u], p[i+1])
}
}
}
// subgraph returns a subgraph of g induced by {s, s+1, ... , n}. The
// subgraph is destructively generated in g.
func (g graph) subgraph(s int) graph {
for u := range g[:s] {
g[u] = nil
}
for u, e := range g[s:] {
for v := range e {
if v < s {
delete(g[u+s], v)
}
}
}
return g
}
// clone returns a deep copy of the graph g.
func (g graph) clone() graph {
c := make(graph, len(g))
for u, e := range g {
for v := range e {
if c[u] == nil {
c[u] = make(set)
}
c[u][v] = struct{}{}
}
}
return c
}