Browse Source

Implement graph data structure

master
Forest Belton 2 years ago
parent
commit
bd83bae2ae
1 changed files with 97 additions and 0 deletions
  1. +97
    -0
      lib/graph/graph.ts

+ 97
- 0
lib/graph/graph.ts View File

@ -0,0 +1,97 @@
export type Graph<V> = {
vertices: {
[v: string]: V
},
edges: {
[v: string]: Set<string>
}
}
export type AddVertex<V> = (name: string, v: V) => void
export type AddEdge = (source: string, dest: string) => void
export const createGraph = <V>(cons: (v: AddVertex<V>, e: AddEdge) => void): Graph<V> => {
const g: Graph<V> = { vertices: {}, edges: {} }
const addVertex = (name: string, v: V) => {
g.vertices[name] = v
g.edges[name] = new Set()
}
const addEdge = (source: string, dest: string) => {
if (typeof g.vertices[source] === "undefined") {
throw new Error(`vertex \`${source}' does not exist in graph`)
} else if (typeof g.vertices[dest] === "undefined") {
throw new Error(`vertex \`${dest}' does not exist in graph`)
}
g.edges[source].add(dest)
g.edges[dest].add(source)
}
cons(addVertex, addEdge)
return g
}
export const neighbors = <V>(g: Graph<V>, name: string): Set<string> => {
if (typeof g.vertices[name] === "undefined") {
throw new Error(`vertex \`${name}' does not exist in graph`)
}
return g.edges[name]
}
export const vertices = <V>(g: Graph<V>): Set<string> => new Set(Object.keys(g.vertices))
export const maxCardinalitySearch = <V>(g: Graph<V>): Array<string> => {
const weights: { [s: string]: number } = {}
const ordering: Array<string> = []
let W = vertices(g)
const numVertices = W.size
for (let i = 0; i < numVertices; ++i) {
const v = findMaxWeight(weights, W)
ordering.push(v)
setIntersect(W, neighbors(g, v)).forEach(x =>
weights[x] = (weights[x] || 0) + 1
)
W.delete(v)
}
return ordering
}
const findMaxWeight = (weights: { [s: string]: number }, W: Set<string>): string => {
let maxV = null
let maxWeight = -Infinity
W.forEach(v => {
const vWeight = weights[v] || 0
if (vWeight > maxWeight) {
maxV = v
maxWeight = vWeight
}
})
if (maxV === null) {
throw new Error(`remaining vertex set is empty`)
}
return maxV
}
const setIntersect = <A>(xs: Set<A>, ys: Set<A>): Set<A> => {
const intersection: Set<A> = new Set()
xs.forEach(x => {
if (ys.has(x)) {
intersection.add(x)
}
})
return intersection
}

Loading…
Cancel
Save