Johnson's SU-distribution

Johnson算法是一种用于有向图的最短路径算法,它的实现基于Bellman-Ford算法和Dijkstra算法。下面是一个使用React实现的Johnson算法: ```jsx import React, { useState } from 'react'; function JohnsonAlgorithm(props) { const [graph, setGraph] = useState(props.graph); const [distance, setDistance] = useState([]); const [path, setPath] = useState([]); function bellmanFord() { const nodes = Object.keys(graph); const edges = Object.values(graph).flat(); const dist = {}; const prev = {}; nodes.forEach((node) => { dist[node] = Infinity; prev[node] = null; }); dist['s'] = 0; for (let i = 0; i < nodes.length - 1; i++) { edges.forEach((edge) => { const u = edge[0]; const v = edge[1]; const w = edge[2]; if (dist[u] !== Infinity && dist[u] + w < dist[v]) { dist[v] = dist[u] + w; prev[v] = u; } }); } return { dist, prev }; } function dijkstra(start, dist, prev) { const nodes = Object.keys(graph); const edges = Object.values(graph).flat(); const visited = {}; const priorityQueue = []; nodes.forEach((node) => { dist[node] = Infinity; prev[node] = null; }); dist[start] = 0; priorityQueue.push(start); while (priorityQueue.length > 0) { const u = priorityQueue.shift(); if (visited[u]) continue; visited[u] = true; edges.forEach((edge) => { const v = edge[1]; const w = edge[2]; if (edge[0] === u && dist[u] + w < dist[v]) { dist[v] = dist[u] + w; prev[v] = u; priorityQueue.push(v); } }); } } function johnson() { const nodes = Object.keys(graph); const edges = Object.values(graph).flat(); const dist = {}; const prev = {}; nodes.push('s'); nodes.forEach((node) => { dist[node] = Infinity; prev[node] = null; }); const { dist: bellmanDist, prev: bellmanPrev } = bellmanFord(); nodes.pop(); nodes.forEach((node) => { graph['s'].push([node, 0]); }); dijkstra('s', dist, prev); nodes.forEach((node) => { dist[node] = dist[node] - bellmanDist['s'] + bellmanDist[node]; }); setDistance(dist); setPath(prev); } return ( <div> <button onClick={johnson}>Run Johnson Algorithm</button> <table> <thead> <tr> <th>Node</th> {Object.keys(graph).map((node) => ( <th key={node}>{node}</th> ))} </tr> </thead> <tbody> {Object.keys(graph).map((node) => ( <tr key={node}> <td>{node}</td> {Object.keys(graph).map((otherNode) => ( <td key={`${node}-${otherNode}`}> {distance[otherNode]} {path[otherNode] && ` (${path[otherNode]})`} </td> ))} </tr> ))} </tbody> </table> </div> ); } export default JohnsonAlgorithm; ``` 上面的代码中,`graph` 是一个对象,其中每个键都是节点,每个值都是一个表示该节点到其他节点的边的数组。例如,下面的代码表示一个图,其中有三个节点A、B、C,以及三条边A->B、B->C和C->A: ```jsx const graph = { A: [ ['B', 2], ], B: [ ['C', 1], ], C: [ ['A', -3], ], }; ``` `distance` 和 `path` 是两个状态,用于存储Johnson算法计算出的最短路径和路径。在 `johnson` 函数中,我们首先对图添加一个虚拟节点`s`,然后运行Bellman-Ford算法计算从`s`到其他节点的最短路径。然后,我们对原图进行修改,将所有边的权重增加一个值,以便它们都是非负数。接下来,我们运行Dijkstra算法计算从`s`到其他节点的最短路径,并使用Bellman-Ford算法计算的结果调整这些路径的权重。最后,我们将最短路径和路径设置为组件的状态,以便它们可以在表格中显示。 在组件的渲染函数中,我们显示一个按钮,当用户点击它时,会运行Johnson算法并更新表格的内容。表格中的每个单元格都显示从一个节点到另一个节点的最短路径长度,以及路径经过的节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值