| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- const _ = require('../lodash')
- const Graph = require('../graph')
- const PriorityQueue = require('../data/priority-queue')
- module.exports = prim
- function prim (g, weightFunc) {
- const result = new Graph()
- const parents = {}
- const pq = new PriorityQueue()
- let v
- function updateNeighbors (edge) {
- const w = edge.v === v ? edge.w : edge.v
- const pri = pq.priority(w)
- if (pri !== undefined) {
- var edgeWeight = weightFunc(edge)
- if (edgeWeight < pri) {
- parents[w] = v
- pq.decrease(w, edgeWeight)
- }
- }
- }
- if (g.nodeCount() === 0) {
- return result
- }
- _.each(g.nodes(), function (v) {
- pq.add(v, Number.POSITIVE_INFINITY)
- result.setNode(v)
- })
- // Start from an arbitrary node
- pq.decrease(g.nodes()[0], 0)
- var init = false
- while (pq.size() > 0) {
- v = pq.removeMin()
- if (_.has(parents, v)) {
- result.setEdge(v, parents[v])
- } else if (init) {
- throw new Error('Input graph is not connected: ' + g)
- } else {
- init = true
- }
- g.nodeEdges(v).forEach(updateNeighbors)
- }
- return result
- }
|