forked from LaconicNetwork/kompose
Upgrade OpenShift and its dependencies.
OpenShift version 1.4.0-alpha.0
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
// 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 path
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/gonum/graph"
|
||||
"github.com/gonum/graph/concrete"
|
||||
"github.com/gonum/graph/internal"
|
||||
)
|
||||
|
||||
// EdgeListerGraph is an undirected graph than returns its complete set of edges.
|
||||
type EdgeListerGraph interface {
|
||||
graph.Undirected
|
||||
Edges() []graph.Edge
|
||||
}
|
||||
|
||||
// Prim generates a minimum spanning tree of g by greedy tree extension, placing
|
||||
// the result in the destination. The destination is not cleared first.
|
||||
func Prim(dst graph.MutableUndirected, g EdgeListerGraph) {
|
||||
var weight graph.WeightFunc
|
||||
if g, ok := g.(graph.Weighter); ok {
|
||||
weight = g.Weight
|
||||
} else {
|
||||
weight = graph.UniformCost
|
||||
}
|
||||
|
||||
nlist := g.Nodes()
|
||||
|
||||
if nlist == nil || len(nlist) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
dst.AddNode(nlist[0])
|
||||
remainingNodes := make(internal.IntSet)
|
||||
for _, node := range nlist[1:] {
|
||||
remainingNodes.Add(node.ID())
|
||||
}
|
||||
|
||||
edgeList := g.Edges()
|
||||
for remainingNodes.Count() != 0 {
|
||||
var edges []concrete.WeightedEdge
|
||||
for _, edge := range edgeList {
|
||||
if (dst.Has(edge.From()) && remainingNodes.Has(edge.To().ID())) ||
|
||||
(dst.Has(edge.To()) && remainingNodes.Has(edge.From().ID())) {
|
||||
|
||||
edges = append(edges, concrete.WeightedEdge{Edge: edge, Cost: weight(edge)})
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(byWeight(edges))
|
||||
myEdge := edges[0]
|
||||
|
||||
dst.SetEdge(myEdge.Edge, myEdge.Cost)
|
||||
remainingNodes.Remove(myEdge.Edge.From().ID())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Kruskal generates a minimum spanning tree of g by greedy tree coalesence, placing
|
||||
// the result in the destination. The destination is not cleared first.
|
||||
func Kruskal(dst graph.MutableUndirected, g EdgeListerGraph) {
|
||||
var weight graph.WeightFunc
|
||||
if g, ok := g.(graph.Weighter); ok {
|
||||
weight = g.Weight
|
||||
} else {
|
||||
weight = graph.UniformCost
|
||||
}
|
||||
|
||||
edgeList := g.Edges()
|
||||
edges := make([]concrete.WeightedEdge, 0, len(edgeList))
|
||||
for _, edge := range edgeList {
|
||||
edges = append(edges, concrete.WeightedEdge{Edge: edge, Cost: weight(edge)})
|
||||
}
|
||||
|
||||
sort.Sort(byWeight(edges))
|
||||
|
||||
ds := newDisjointSet()
|
||||
for _, node := range g.Nodes() {
|
||||
ds.makeSet(node.ID())
|
||||
}
|
||||
|
||||
for _, edge := range edges {
|
||||
// The disjoint set doesn't really care for which is head and which is tail so this
|
||||
// should work fine without checking both ways
|
||||
if s1, s2 := ds.find(edge.Edge.From().ID()), ds.find(edge.Edge.To().ID()); s1 != s2 {
|
||||
ds.union(s1, s2)
|
||||
dst.SetEdge(edge.Edge, edge.Cost)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type byWeight []concrete.WeightedEdge
|
||||
|
||||
func (e byWeight) Len() int {
|
||||
return len(e)
|
||||
}
|
||||
|
||||
func (e byWeight) Less(i, j int) bool {
|
||||
return e[i].Cost < e[j].Cost
|
||||
}
|
||||
|
||||
func (e byWeight) Swap(i, j int) {
|
||||
e[i], e[j] = e[j], e[i]
|
||||
}
|
||||
Reference in New Issue
Block a user