// 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 Weighting if wg, ok := g.(graph.Weighter); ok { weight = wg.Weight } else { weight = UniformCost(g) } nlist := g.Nodes() if nlist == nil || len(nlist) == 0 { return } dst.AddNode(nlist[0]) remain := make(internal.IntSet) for _, node := range nlist[1:] { remain.Add(node.ID()) } edgeList := g.Edges() for remain.Count() != 0 { var edges []concrete.Edge for _, e := range edgeList { u := e.From() v := e.To() if (dst.Has(u) && remain.Has(v.ID())) || (dst.Has(v) && remain.Has(u.ID())) { w, ok := weight(u, v) if !ok { panic("prim: unexpected invalid weight") } edges = append(edges, concrete.Edge{F: u, T: v, W: w}) } } sort.Sort(byWeight(edges)) min := edges[0] dst.SetEdge(min) remain.Remove(min.From().ID()) } }
// 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()) } }