UNPKG

@fluxgraph/knowledge

Version:

A flexible, database-agnostic knowledge graph implementation for TypeScript

1 lines 18.9 kB
{"version":3,"sources":["../../src/algorithms/index.ts"],"sourcesContent":["import { KnowledgeGraph } from '../core/KnowledgeGraph';\nimport { KnowledgeNode, KnowledgeEdge } from '../types';\n\n/**\n * Graph algorithms for analyzing and working with knowledge graphs\n */\nexport class GraphAlgorithms {\n private graph: KnowledgeGraph;\n \n constructor(graph: KnowledgeGraph) {\n this.graph = graph;\n }\n \n /**\n * Calculate degree centrality for a node\n * Degree centrality is the number of edges connected to a node\n */\n async degreeCentrality(nodeId: string): Promise<number> {\n const result = await this.graph.queryRelated(nodeId, { depth: 1 });\n return result.edges.length;\n }\n \n /**\n * Calculate degree centrality for all nodes\n */\n async allDegreeCentrality(): Promise<Map<string, number>> {\n const centrality = new Map<string, number>();\n \n // This is a simplified implementation\n // In production, you'd want to batch this operation\n const nodes = await this.graph.queryByType('CUSTOM', { limit: 1000 });\n \n for (const node of nodes.nodes) {\n const degree = await this.degreeCentrality(node.id);\n centrality.set(node.id, degree);\n }\n \n return centrality;\n }\n \n /**\n * Find all paths between two nodes up to a maximum length\n */\n async findAllPaths(\n fromNodeId: string,\n toNodeId: string,\n maxLength = 5\n ): Promise<Array<{ nodes: KnowledgeNode[]; edges: KnowledgeEdge[]; length: number }>> {\n const paths: Array<{ nodes: KnowledgeNode[]; edges: KnowledgeEdge[]; length: number }> = [];\n \n // Use DFS to find all paths\n const visited = new Set<string>();\n const currentPath: string[] = [];\n const currentEdges: KnowledgeEdge[] = [];\n \n const dfs = async (currentNodeId: string, depth: number) => {\n if (depth > maxLength) return;\n \n if (currentNodeId === toNodeId) {\n // Found a path\n const nodeObjects = await Promise.all(\n [...currentPath, currentNodeId].map(id => this.graph.getNode(id))\n );\n \n paths.push({\n nodes: nodeObjects.filter(n => n !== null) as KnowledgeNode[],\n edges: [...currentEdges],\n length: currentPath.length,\n });\n return;\n }\n \n if (visited.has(currentNodeId)) return;\n \n visited.add(currentNodeId);\n currentPath.push(currentNodeId);\n \n // Get all outgoing edges\n const result = await this.graph.queryRelated(currentNodeId, { \n depth: 1, \n direction: 'out' \n });\n \n for (const edge of result.edges) {\n if (edge.fromNodeId === currentNodeId) {\n currentEdges.push(edge);\n await dfs(edge.toNodeId, depth + 1);\n currentEdges.pop();\n }\n }\n \n currentPath.pop();\n visited.delete(currentNodeId);\n };\n \n await dfs(fromNodeId, 0);\n return paths;\n }\n \n /**\n * Detect cycles in the graph\n */\n async detectCycles(): Promise<Array<{ nodes: string[]; edges: KnowledgeEdge[] }>> {\n const cycles: Array<{ nodes: string[]; edges: KnowledgeEdge[] }> = [];\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const path: string[] = [];\n const pathEdges: KnowledgeEdge[] = [];\n \n const dfs = async (nodeId: string): Promise<boolean> => {\n visited.add(nodeId);\n recursionStack.add(nodeId);\n path.push(nodeId);\n \n const result = await this.graph.queryRelated(nodeId, { \n depth: 1, \n direction: 'out' \n });\n \n for (const edge of result.edges) {\n if (edge.fromNodeId === nodeId) {\n pathEdges.push(edge);\n \n if (!visited.has(edge.toNodeId)) {\n if (await dfs(edge.toNodeId)) {\n return true;\n }\n } else if (recursionStack.has(edge.toNodeId)) {\n // Found a cycle\n const cycleStartIndex = path.indexOf(edge.toNodeId);\n cycles.push({\n nodes: path.slice(cycleStartIndex),\n edges: pathEdges.slice(cycleStartIndex),\n });\n }\n \n pathEdges.pop();\n }\n }\n \n path.pop();\n recursionStack.delete(nodeId);\n return false;\n };\n \n // Check all nodes for cycles\n const nodes = await this.graph.queryByType('CUSTOM', { limit: 1000 });\n \n for (const node of nodes.nodes) {\n if (!visited.has(node.id)) {\n await dfs(node.id);\n }\n }\n \n return cycles;\n }\n \n /**\n * Find connected components in the graph\n */\n async findConnectedComponents(): Promise<Array<Set<string>>> {\n const components: Array<Set<string>> = [];\n const visited = new Set<string>();\n \n const dfs = async (nodeId: string, component: Set<string>) => {\n if (visited.has(nodeId)) return;\n \n visited.add(nodeId);\n component.add(nodeId);\n \n const result = await this.graph.queryRelated(nodeId, { \n depth: 1, \n direction: 'both' \n });\n \n for (const node of result.nodes) {\n if (node.id !== nodeId && !visited.has(node.id)) {\n await dfs(node.id, component);\n }\n }\n };\n \n // Get all nodes\n const nodes = await this.graph.queryByType('CUSTOM', { limit: 10000 });\n \n for (const node of nodes.nodes) {\n if (!visited.has(node.id)) {\n const component = new Set<string>();\n await dfs(node.id, component);\n components.push(component);\n }\n }\n \n return components;\n }\n \n /**\n * Calculate PageRank for all nodes\n * Simplified implementation - real PageRank would need iterative computation\n */\n async pageRank(\n damping = 0.85,\n iterations = 10\n ): Promise<Map<string, number>> {\n const pageRank = new Map<string, number>();\n const nodes = await this.graph.queryByType('CUSTOM', { limit: 10000 });\n const nodeIds = nodes.nodes.map(n => n.id);\n const N = nodeIds.length;\n \n // Initialize PageRank values\n for (const nodeId of nodeIds) {\n pageRank.set(nodeId, 1 / N);\n }\n \n // Iterative computation\n for (let iter = 0; iter < iterations; iter++) {\n const newPageRank = new Map<string, number>();\n \n for (const nodeId of nodeIds) {\n let rank = (1 - damping) / N;\n \n // Get incoming edges\n const result = await this.graph.queryRelated(nodeId, { \n depth: 1, \n direction: 'in' \n });\n \n for (const edge of result.edges) {\n if (edge.toNodeId === nodeId) {\n const sourceRank = pageRank.get(edge.fromNodeId) || 0;\n const sourceOutDegree = await this.degreeCentrality(edge.fromNodeId);\n rank += damping * (sourceRank / Math.max(sourceOutDegree, 1));\n }\n }\n \n newPageRank.set(nodeId, rank);\n }\n \n // Update PageRank values\n for (const [nodeId, rank] of newPageRank) {\n pageRank.set(nodeId, rank || 0);\n }\n }\n \n return pageRank;\n }\n \n /**\n * Find nodes that form a clique (fully connected subgraph)\n */\n async findCliques(minSize = 3): Promise<Array<Set<string>>> {\n const cliques: Array<Set<string>> = [];\n const nodes = await this.graph.queryByType('CUSTOM', { limit: 1000 });\n const nodeIds = nodes.nodes.map(n => n.id);\n \n // Bron-Kerbosch algorithm (simplified)\n const bronKerbosch = async (\n R: Set<string>,\n P: Set<string>,\n X: Set<string>\n ) => {\n if (P.size === 0 && X.size === 0) {\n if (R.size >= minSize) {\n cliques.push(new Set(R));\n }\n return;\n }\n \n for (const v of P) {\n const neighbors = new Set<string>();\n const result = await this.graph.queryRelated(v, { depth: 1 });\n \n for (const node of result.nodes) {\n if (node.id !== v) {\n neighbors.add(node.id);\n }\n }\n \n const newR = new Set(R);\n newR.add(v);\n \n const newP = new Set<string>();\n for (const p of P) {\n if (neighbors.has(p)) newP.add(p);\n }\n \n const newX = new Set<string>();\n for (const x of X) {\n if (neighbors.has(x)) newX.add(x);\n }\n \n await bronKerbosch(newR, newP, newX);\n \n P.delete(v);\n X.add(v);\n }\n };\n \n await bronKerbosch(new Set(), new Set(nodeIds), new Set());\n return cliques;\n }\n \n /**\n * Calculate clustering coefficient for a node\n */\n async clusteringCoefficient(nodeId: string): Promise<number> {\n const result = await this.graph.queryRelated(nodeId, { depth: 1 });\n const neighbors = result.nodes.filter(n => n.id !== nodeId);\n \n if (neighbors.length < 2) return 0;\n \n let triangles = 0;\n const possibleTriangles = (neighbors.length * (neighbors.length - 1)) / 2;\n \n // Check how many neighbors are connected to each other\n for (let i = 0; i < neighbors.length; i++) {\n for (let j = i + 1; j < neighbors.length; j++) {\n const neighborI = neighbors[i];\n const neighborJ = neighbors[j];\n if (!neighborI || !neighborJ) continue;\n \n const edges = await this.graph.getEdgesBetween(\n neighborI.id,\n neighborJ.id\n );\n \n if (edges.length > 0) {\n triangles++;\n }\n }\n }\n \n return triangles / possibleTriangles;\n }\n \n /**\n * Find communities using label propagation\n */\n async detectCommunities(): Promise<Map<string, number>> {\n const communities = new Map<string, number>();\n const nodes = await this.graph.queryByType('CUSTOM', { limit: 1000 });\n \n // Initialize each node with its own community\n let communityId = 0;\n for (const node of nodes.nodes) {\n communities.set(node.id, communityId++);\n }\n \n // Iterate until convergence\n let changed = true;\n let iterations = 0;\n const maxIterations = 10;\n \n while (changed && iterations < maxIterations) {\n changed = false;\n iterations++;\n \n for (const node of nodes.nodes) {\n const result = await this.graph.queryRelated(node.id, { depth: 1 });\n \n // Count community labels of neighbors\n const labelCounts = new Map<number, number>();\n \n for (const neighbor of result.nodes) {\n if (neighbor.id !== node.id) {\n const label = communities.get(neighbor.id);\n if (label !== undefined) {\n labelCounts.set(label, (labelCounts.get(label) || 0) + 1);\n }\n }\n }\n \n // Adopt the most common label\n if (labelCounts.size > 0) {\n const maxLabel = Array.from(labelCounts.entries())\n .reduce((a, b) => a[1] > b[1] ? a : b)[0];\n \n if (communities.get(node.id) !== maxLabel) {\n communities.set(node.id, maxLabel);\n changed = true;\n }\n }\n }\n }\n \n return communities;\n }\n}\n\n// Export convenience functions\nexport async function degreeCentrality(graph: KnowledgeGraph, nodeId: string): Promise<number> {\n const algorithms = new GraphAlgorithms(graph);\n return algorithms.degreeCentrality(nodeId);\n}\n\nexport async function findShortestPath(\n graph: KnowledgeGraph,\n fromNodeId: string,\n toNodeId: string\n): Promise<any> {\n return graph.findShortestPath(fromNodeId, toNodeId);\n}\n\nexport async function detectCycles(graph: KnowledgeGraph): Promise<any> {\n const algorithms = new GraphAlgorithms(graph);\n return algorithms.detectCycles();\n}\n\nexport async function pageRank(graph: KnowledgeGraph): Promise<Map<string, number>> {\n const algorithms = new GraphAlgorithms(graph);\n return algorithms.pageRank();\n}"],"mappings":"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","names":["pageRank"]}