文心一言 VS 讯飞星火 VS chatgpt (364)-- 算法导论24.3 6题

news2024/10/7 21:56:23

六、给定有向图 G = ( V , E ) G=(V,E) G=(V,E),每条边 ( u , v ) ∈ E (u,v)∈E (u,v)E 有一个关联值 r ( u , v ) r(u,v) r(u,v) ,该关联值是一个实数,其范围为 0 ⩽ r ( u , v ) ⩽ 1 0⩽r(u,v)⩽1 0r(u,v)1 ,其代表的意思是从结点 u u u到结点 v v v之间的通信链路的可靠性。可以认为, r ( u , v ) r(u,v) r(u,v) 代表的是从结点 u u u 到结点 v v v 的通信链路不失效的概率,并且假设这些概率之间相互独立。请给出一个有效的算法来找到任意两个结点之间最可靠的通信链路。如果要写代码,请用go语言。

文心一言:

要在有向图 G = ( V , E ) G=(V,E) G=(V,E) 中找到任意两个结点之间最可靠的通信链路,可以使用 Floyd-Warshall 算法进行求解。Floyd-Warshall 算法是一个经典的动态规划算法,用于计算所有结点对之间的最短路径(在这里,我们将其改造成计算所有结点对之间的最大可靠性路径)。

下面是一个使用 Go 语言实现的算法,其中 graph 表示有向图,reliability 是一个二维数组,用于存储任意两个结点之间的最大可靠性。

package main

import (
	"fmt"
	"math"
)

// Edge represents an edge in the graph with a reliability value
type Edge struct {
	to     int
	rel    float64
}

// Graph represents a directed graph
type Graph struct {
	vertices int
	edges    map[int][]Edge
}

// NewGraph creates a new graph with a given number of vertices
func NewGraph(vertices int) *Graph {
	return &Graph{
		vertices: vertices,
		edges:    make(map[int][]Edge),
	}
}

// AddEdge adds an edge to the graph with a given reliability
func (g *Graph) AddEdge(from, to int, rel float64) {
	if rel < 0 || rel > 1 {
		panic("Reliability must be in the range [0, 1]")
	}
	g.edges[from] = append(g.edges[from], Edge{to, rel})
}

// FloydWarshall computes the most reliable path between all pairs of vertices
func (g *Graph) FloydWarshall() [][]float64 {
	// Initialize reliability matrix with zero values
	reliability := make([][]float64, g.vertices)
	for i := range reliability {
		reliability[i] = make([]float64, g.vertices)
		for j := range reliability[i] {
			reliability[i][j] = 0.0
		}
	}

	// Set direct edges' reliability
	for from, edges := range g.edges {
		for _, edge := range edges {
			reliability[from][edge.to] = edge.rel
		}
	}

	// Set self-loops to 1 (max reliability for direct path to self)
	for i := 0; i < g.vertices; i++ {
		reliability[i][i] = 1.0
	}

	// Floyd-Warshall algorithm
	for k := 0; k < g.vertices; k++ {
		for i := 0; i < g.vertices; i++ {
			for j := 0; j < g.vertices; j++ {
				if reliability[i][k]*reliability[k][j] > reliability[i][j] {
					reliability[i][j] = reliability[i][k] * reliability[k][j]
				}
			}
		}
	}

	return reliability
}

func main() {
	// Example usage
	graph := NewGraph(5)
	graph.AddEdge(0, 1, 0.8)
	graph.AddEdge(0, 2, 0.9)
	graph.AddEdge(1, 2, 0.7)
	graph.AddEdge(1, 3, 0.6)
	graph.AddEdge(2, 3, 0.5)
	graph.AddEdge(3, 4, 0.4)
	graph.AddEdge(2, 4, 0.2)

	reliability := graph.FloydWarshall()

	// Print the reliability matrix
	for i := 0; i < graph.vertices; i++ {
		for j := 0; j < graph.vertices; j++ {
			if math.IsNaN(reliability[i][j]) {
				fmt.Printf("INF ") // If there's no path, we could print INF or some other indicator
			} else {
				fmt.Printf("%.2f ", reliability[i][j])
			}
		}
		fmt.Println()
	}
}

解释

  1. Graph 数据结构

    • Graph 结构体包含顶点数量和边的映射。
    • AddEdge 方法用于添加边,并验证可靠性是否在 [0, 1] 范围内。
  2. Floyd-Warshall 算法

    • 初始化可靠性矩阵 reliability,将所有值设为 0。
    • 设置直接边的可靠性值。
    • 设置自环的可靠性为 1(即每个顶点到自身的可靠性最高)。
    • 使用三重循环更新可靠性矩阵,找到所有结点对之间的最大可靠性路径。
  3. 主函数

    • 创建一个示例图并添加一些边。
    • 调用 FloydWarshall 方法计算可靠性矩阵。
    • 打印可靠性矩阵。

注意

  • 如果没有路径,可靠性值会被初始化为 0,但你也可以选择使用 math.NaN() 或其他方式来表示不可达路径。
  • 代码假设输入是有效的,即没有重复的边和顶点索引在有效范围内。

这个算法的时间复杂度是 O ( V 3 ) O(V^3) O(V3),其中 V V V 是顶点的数量,适用于顶点数量不太大的情况。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

讯飞星火:

为了找到任意两个结点之间最可靠的通信链路,我们可以使用Floyd-Warshall算法。这个算法可以在有向图中找到所有结点对之间的最短路径,同时考虑边的权重(在这里是可靠性)。

以下是用Go语言实现的Floyd-Warshall算法:

package main

import (
	"fmt"
)

func floydWarshall(graph [][]float64, n int) [][]float64 {
	// 初始化距离矩阵
	dist := make([][]float64, n)
	for i := range dist {
		dist[i] = make([]float64, n)
		for j := range dist[i] {
			if i == j {
				dist[i][j] = 1.0 // 从节点到自身的距离为1
			} else if graph[i][j] != 0 {
				dist[i][j] = graph[i][j] // 如果有边,则直接使用边的可靠性作为距离
			} else {
				dist[i][j] = 0.0 // 如果没有边,则距离为0
			}
		}
	}

	// 更新距离矩阵
	for k := 0; k < n; k++ {
		for i := 0; i < n; i++ {
			for j := 0; j < n; j++ {
				if dist[i][k]*dist[k][j] > dist[i][j] {
					dist[i][j] = dist[i][k] * dist[k][j]
				}
			}
		}
	}

	return dist
}

func main() {
	// 示例有向图,其中graph[i][j]表示从节点i到节点j的可靠性
	graph := [][]float64{
		{0, 0.9, 0, 0},
		{0, 0, 0.8, 0},
		{0, 0, 0, 0.7},
		{0, 0, 0, 0},
	}

	n := len(graph)
	dist := floydWarshall(graph, n)

	// 输出结果
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			fmt.Printf("%.2f ", dist[i][j])
		}
		fmt.Println()
	}
}

在这个代码中,我们首先初始化一个距离矩阵dist,然后使用Floyd-Warshall算法更新这个矩阵。最后,我们输出更新后的距离矩阵,其中dist[i][j]表示从节点i到节点j的最可靠通信链路的可靠性。

360智脑:

为了找到任意两个结点之间最可靠的通信链路,我们可以使用动态规划或者图的最短路径算法的一种变体。由于我们是在寻找最大概率的路径,而不是最小权重的路径,我们需要对传统的Dijkstra算法或Bellman-Ford算法进行一些修改。这里我将提供一个基于Dijkstra算法的变体,用于解决这个问题。

以下是Go语言实现的代码:

import (
	"container/heap"
)

type Edge struct {
	To     int
	Reli   float64
}

type Graph struct {
	Nodes [][]Edge
}

type Item struct {
	Node int
	Prob float64
	index int
}

type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].Prob > pq[j].Prob
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Item)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil
	item.index = -1
	*pq = old[0 : n-1]
	return item
}

func NewGraph(edges [][]Edge) *Graph {
	g := &Graph{make([][]Edge, len(edges))}
	for i, edgeList := range edges {
		g.Nodes[i] = make([]Edge, len(edgeList))
		copy(g.Nodes[i], edgeList)
	}
	return g
}

func MostReliablePath(g *Graph, start, end int) float64 {
	pq := make(PriorityQueue, 0)
	heap.Init(&pq)

	dist := make([]float64, len(g.Nodes))
	for i := range dist {
		dist[i] = 0
	}
	dist[start] = 1 // 开始节点到自身的可靠性为1

	heap.Push(&pq, &Item{Node: start, Prob: 1})

	for pq.Len() > 0 {
		item := heap.Pop(&pq).(*Item)
		node := item.Node

		if node == end {
			break
		}

		for _, edge := range g.Nodes[node] {
			newProb := dist[node] * edge.Reli
			if newProb > dist[edge.To] {
				dist[edge.To] = newProb
				heap.Push(&pq, &Item{Node: edge.To, Prob: newProb})
			}
		}
	}

	return dist[end]
}

在这个实现中,我们定义了一个Edge结构体来存储边的信息,包括目标节点和可靠性。Graph结构体表示整个图,它包含一个切片,每个元素都是一个Edge切片的列表,表示每个节点的出边。

我们还定义了一个优先队列(PriorityQueue)和一个Item结构体,用于在Dijkstra算法中跟踪每个节点的最大可靠性。

MostReliablePath函数实现了我们的算法。它初始化距离数组和优先队列,然后开始遍历图,更新每个节点的最大可靠性,直到找到终点或遍历完所有可达节点。

要使用这个函数,你需要创建一个Graph实例,并调用MostReliablePath函数,传入起始节点和结束节点。函数将返回这两个节点之间的最可靠通信链路的可靠性。

智谱清言:

这个问题可以通过动态规划算法来解决,类似于求解最短路径的Floyd-Warshall算法。我们可以定义一个二维数组dp,其中dp[i][j]表示从结点i到结点j之间最可靠的通信链路的可靠性值。算法的基本思想是,通过考虑所有可能的中间结点,逐步更新dp数组中的值。
以下是使用Go语言实现的算法:

package main
import (
	"fmt"
	"math"
)
// 定义图的结构
type Graph struct {
	Vertices int
	Edges    map[int]map[int]float64
}
// 初始化图
func NewGraph(vertices int) *Graph {
	return &Graph{
		Vertices: vertices,
		Edges:    make(map[int]map[int]float64),
	}
}
// 添加边
func (g *Graph) AddEdge(u, v int, r float64) {
	if g.Edges[u] == nil {
		g.Edges[u] = make(map[int]float64)
	}
	g.Edges[u][v] = r
}
// 计算最可靠的通信链路
func (g *Graph) MostReliablePath() [][]float64 {
	// 初始化dp数组,所有值设为0
	dp := make([][]float64, g.Vertices)
	for i := range dp {
		dp[i] = make([]float64, g.Vertices)
		for j := range dp[i] {
			if i == j {
				dp[i][j] = 1 // 自己到自己的可靠性为1
			} else {
				dp[i][j] = 0
			}
		}
	}
	// 更新直接连接的边的可靠性
	for u := 0; u < g.Vertices; u++ {
		if g.Edges[u] != nil {
			for v, r := range g.Edges[u] {
				dp[u][v] = r
			}
		}
	}
	// 使用Floyd-Warshall算法更新dp数组
	for k := 0; k < g.Vertices; k++ {
		for i := 0; i < g.Vertices; i++ {
			for j := 0; j < g.Vertices; j++ {
				dp[i][j] = math.Max(dp[i][j], dp[i][k]*dp[k][j])
			}
		}
	}
	return dp
}
func main() {
	g := NewGraph(4)
	g.AddEdge(0, 1, 0.9)
	g.AddEdge(0, 2, 0.5)
	g.AddEdge(1, 2, 0.8)
	g.AddEdge(2, 0, 0.7)
	g.AddEdge(2, 3, 0.6)
	g.AddEdge(3, 3, 1.0) // 自环
	dp := g.MostReliablePath()
	for i := range dp {
		for j := range dp[i] {
			fmt.Printf("从结点%d到结点%d的最可靠通信链路可靠性为: %.2f\n", i, j, dp[i][j])
		}
	}
}

在这个代码中,我们首先定义了一个图的结构,并提供了添加边的方法。然后,我们实现了MostReliablePath方法来计算任意两个结点之间最可靠的通信链路。最后,在main函数中,我们创建了一个图,添加了一些边,并计算了最可靠的通信链路。
这个算法的时间复杂度是 O ( V 3 ) O(V^3) O(V3),其中 V V V是图中结点的数量。对于稠密图来说,这是一个有效的算法。如果图非常稀疏,可以考虑使用其他算法,如基于优先队列的Dijkstra算法变种,来提高效率。

天工:

为了找到有向图中任意两点间最可靠的通信路径,我们可以使用类似于Dijkstra算法的方法,但需要进行一些调整以适应可靠性这一特性。由于我们关心的是最大概率路径,我们需要在每一步中都选择能够最大化路径总可靠性的边。在概率乘法原理下,路径的总可靠性是路径上每条边的可靠性相乘的结果。

算法步骤

  1. 初始化:为起点s创建一个空的优先队列Q,并初始化距离数组d,其中d[s] = 1(起点到自身的可靠性为1),其余节点的可靠性为0。同时,创建一个前驱节点数组p,用于记录最短路径上的前驱节点。

  2. 循环处理:从优先队列Q中取出可靠性最大的节点u(初始化时为起点s),然后遍历u的所有出边(u, v)。对于每个邻接点v,计算通过u到达v的可靠性:newReliability = d[u] * r(u, v)。如果newReliability > d[v],则更新d[v]和p[v]。

  3. 更新优先队列:更新后的节点v需要被重新加入优先队列中,以便在下一轮中被正确处理。

  4. 重复步骤2和3,直到优先队列Q为空。

Go代码实现

package main

import (
	"container/heap"
	"fmt"
)

type Node struct {
	id       int
	reliabl  float64
	index    int
	heapIdx  int
}

type PriorityQueue []*Node

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].reliabl > pq[j].reliabl
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].heapIdx = i
	pq[j].heapIdx = j
}

func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	node := x.(*Node)
	node.heapIdx = n
	*pq = append(*pq, node)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	node := old[n-1]
	old[n-1] = nil
	node.heapIdx = -1
	*pq = old[0 : n-1]
	return node
}

func updatePriorityQueue(pq *PriorityQueue, node *Node) {
	heap.Fix(pq, node.heapIdx)
}

func maxReliabilityPath(graph [][]float64, start int) {
	n := len(graph)
	d := make([]float64, n)
	p := make([]int, n)
	for i := range d {
		d[i] = 0
		p[i] = -1
	}
	d[start] = 1
	pq := &PriorityQueue{}
	heap.Init(pq)
	node := &Node{start, 1, start, -1}
	heap.Push(pq, node)
	for pq.Len() > 0 {
		u := heap.Pop(pq).(*Node)
		for v := range graph[u.id] {
			newReliability := d[u.id] * graph[u.id][v]
			if newReliability > d[v] {
				d[v] = newReliability
				p[v] = u.id
				node := &Node{v, newReliability, v, -1}
				heap.Push(pq, node)
				updatePriorityQueue(pq, node)
			}
		}
	}
	fmt.Println("Reliability distances:", d)
	fmt.Println("Predecessor array:", p)
}

func main() {
	graph := [][]float64{
		{0, 0.5, 0.2, 0},
		{0, 0, 0.1, 0.7},
		{0, 0, 0, 0.3},
		{0, 0, 0, 0},
	}
	maxReliabilityPath(graph, 0) // Assuming 0 is the start node
}

说明

  • 上述代码中,graph 是一个邻接矩阵,其中graph[u][v]表示边(u, v)的可靠性。
  • maxReliabilityPath 函数计算从指定起点到所有其他节点的最可靠路径。
  • 使用了优先队列来保证每次处理的节点是最可靠的。
  • d 数组存储了最可靠路径的可靠性,而 p 数组存储了最短路径上的前驱节点。

chatgpt:

要找到任意两个结点之间最可靠的通信链路,可以使用动态规划算法来解决。以下是一个用Go语言实现的示例代码:

package main

import (
	"fmt"
	"math"
)

func maxReliablePath(G [][]float64, start, end int) float64 {
	n := len(G)
	dp := make([][]float64, n)
	for i := range dp {
		dp[i] = make([]float64, n)
	}

	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			dp[i][j] = G[i][j]
		}
	}

	for k := 0; k < n; k++ {
		for i := 0; i < n; i++ {
			for j := 0; j < n; j++ {
				dp[i][j] = math.Max(dp[i][j], dp[i][k]*dp[k][j])
			}
		}
	}

	return dp[start][end]
}

func main() {
	G := [][]float64{
		{0, 0.5, 0.8},
		{0.4, 0, 0.1},
		{0.2, 0.9, 0},
	}

	start := 0
	end := 2

	result := maxReliablePath(G, start, end)
	fmt.Printf("The maximum reliability between node %d and node %d is: %.2f\n", start, end, result)
}

在示例代码中,我们使用一个二维数组G来表示图中每条边的可靠性值。函数maxReliablePath接受一个邻接矩阵和起点、终点的索引,然后计算从起点到终点的最大可靠性。

你可以根据自己的实际需求修改G和起点、终点的值,然后运行这段代码来得到任意两个结点之间最可靠的通信链路的可靠性值。

kimi:

为了找到有向图 ( G = (V, E) ) 中任意两个结点之间最可靠的通信链路,我们可以使用 Dijkstra 算法的变体,该算法考虑了边的可靠性。以下是算法的逐步解释和 Go 语言的实现:

算法步骤:

  1. 初始化:对于每个顶点 ( v \in V ),设置一个距离数组 ( dist[v] ) 来存储从源顶点 ( s ) 到顶点 ( v ) 的最可靠路径的概率。将 ( s ) 的距离设置为 1(因为从自身到自身的可靠性是 1),将所有其他顶点的距离设置为 0。
  2. 优先队列:使用一个优先队列(最小堆)来存储顶点及其距离,以便每次都能扩展最可靠的顶点。
  3. 松弛操作:对于每个顶点 ( u ),检查其所有出边 ( (u, v) )。如果通过 ( u ) 到 ( v ) 的路径比当前已知的路径更可靠,则更新 ( v ) 的距离并将 ( v ) 重新加入优先队列。
  4. 终止条件:当优先队列为空或找到目标顶点 ( t ) 时,算法终止。

Go 语言实现:

package main

import (
	"container/heap"
	"fmt"
)

type Edge struct {
	To   int
	Reliability float64
}

type Vertex struct {
	Name    int
	Edges   []*Edge
}

type PriorityQueue []*Vertex

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].dist > pq[j].dist
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueue) Push(x interface{}) {
	*pq = append(*pq, x.(*Vertex))
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	x := old[n-1]
	*pq = old[0 : n-1]
	return x
}

func (v *Vertex) updateDistance(newDist float64) {
	if newDist > v.dist {
		v.dist = newDist
		heap.Push(&pq, v)
	}
}

func findMostReliablePath(graph []*Vertex, src, dst int) float64 {
	pq := make(PriorityQueue, 0)
	heap.Init(&pq)

	for _, v := range graph {
		v.dist = 0
	}
	graph[src].dist = 1

	heap.Push(&pq, graph[src])

	for pq.Len() > 0 {
		u := heap.Pop(&pq).(*Vertex)

		if u.Name == dst {
			return u.dist
		}

		for _, edge := range u.Edges {
			v := edge.To
			newDist := u.dist * edge.Reliability
			graph[v].updateDistance(newDist)
		}
	}

	return 0
}

func main() {
	// Example graph construction
	vertices := []*Vertex{
		{Name: 0}, {Name: 1}, {Name: 2}, {Name: 3},
	}
	edges := []*Edge{
		{To: 1, Reliability: 0.9}, {To: 2, Reliability: 0.7},
		{To: 2, Reliability: 0.8}, {To: 3, Reliability: 0.5},
		{To: 3, Reliability: 0.6}, {To: 1, Reliability: 0.4},
	}

	for i, edge := range edges {
		vertices[edge.To].Edges = append(vertices[edge.To].Edges, &Edge{To: i, Reliability: edge.Reliability})
	}

	src, dst := 0, 3
	fmt.Printf("Most reliable path from %d to %d has reliability: %f\n", src, dst, findMostReliablePath(vertices, src, dst))
}

说明:

  • 这段代码定义了一个有向图,其中包含顶点和边。
  • 它使用优先队列来找到从源顶点到目标顶点的最可靠路径。
  • findMostReliablePath 函数返回两个顶点之间最可靠路径的可靠性。

这个算法确保了在每一步都扩展最可靠的顶点,从而在终止时找到最可靠的路径。

混元:

要找到有向图中任意两个节点之间最可靠的通信路径,我们可以使用Dijkstra算法的变种,因为我们需要找到从起点到终点的最大概率(即最可靠路径)。以下是解决这个问题的思路:

  1. 初始化:创建一个图表示所有节点和边的可靠性。对于每个节点,初始化一个到自身的可靠性为1(因为从任何节点到自身的路径总是可靠的),其他节点的可靠性初始化为0。

  2. 使用优先队列(最大堆)来存储节点和它们的可靠性,初始时将起始节点放入队列中。

  3. 当优先队列不为空时,重复以下步骤:
    a. 从队列中取出可靠性最高的节点。
    b. 对于该节点的每个邻居,计算通过当前节点到达邻居的可靠性(即当前节点的可靠性乘以边的可靠性)。
    c. 如果这个新的可靠性大于邻居当前的可靠性,则更新邻居的可靠性,并将邻居及其新的可靠性放入优先队列中。

  4. 当终点节点被处理后,其可靠性就是从起点到终点的最可靠路径的可靠性。

  5. 为了找到具体的路径,我们可以在更新邻居的可靠性时,记录每个节点的前驱节点。这样,在找到最可靠路径的可靠性后,我们可以从终点回溯到起点,构建出完整的路径。

以下是Go语言实现的代码:

package main

import (
	"container/heap"
	"fmt"
)

type Edge struct {
	to     int
	reliability float64
}

type Node struct {
	index int
	reliability float64
}

type PriorityQueue []*Node

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].reliability > pq[j].reliability
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	node := x.(*Node)
	node.index = n
	*pq = append(*pq, node)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	node := old[n-1]
	node.index = -1 // for safety
	*pq = old[0 : n-1]
	return node
}

func findReliablePath(graph [][]Edge, start, end int) (float64, []int) {
	n := len(graph)
	reliabilities := make([]float64, n)
	previous := make([]int, n)
	for i := range reliabilities {
		reliabilities[i] = 0
		previous[i] = -1
	}
	reliabilities[start] = 1

	pq := make(PriorityQueue, 0)
	heap.Push(&pq, &Node{index: start, reliability: 1})

	for pq.Len() > 0 {
		current := heap.Pop(&pq).(*Node)
		if current.index == end {
			break
		}
		for _, edge := range graph[current.index] {
			newReliability := current.reliability * edge.reliability
			if newReliability > reliabilities[edge.to] {
				reliabilities[edge.to] = newReliability
				previous[edge.to] = current.index
				heap.Push(&pq, &Node{index: edge.to, reliability: newReliability})
			}
		}
	}

	// Reconstruct path
	path := make([]int, 0)
	for current := end; current != -1; current = previous[current] {
		path = append([]int{current}, path...)
	}

	return reliabilities[end], path
}

func main() {
	graph := [][]Edge{
		{{1, 0.9}, {2, 0.8}},
		{{2, 0.7}, {3, 0.6}},
		{{3, 0.5}},
		{},
	}
	start := 0
	end := 3
	reliability, path := findReliablePath(graph, start, end)
	fmt.Printf("The most reliable path from %d to %d has reliability %.2f and the path is %v\n", start, end, reliability, path)
}

在这段代码中,我们定义了Edge结构体来表示图中的边和它们的可靠性,Node结构体来表示优先队列中的节点和它们的可靠性,以及PriorityQueue类型来实现一个最大堆。findReliablePath函数实现了寻找最可靠路径的算法,并返回路径的可靠性和路径本身。最后,main函数提供了一个示例图,并调用findReliablePath函数来找到从节点0到节点3的最可靠路径。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2194966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sleuth、Zipkin学习

系列文章目录 JavaSE基础知识、数据类型学习万年历项目代码逻辑训练习题代码逻辑训练习题方法、数组学习图书管理系统项目面向对象编程&#xff1a;封装、继承、多态学习封装继承多态习题常用类、包装类、异常处理机制学习集合学习IO流、多线程学习仓库管理系统JavaSE项目员工…

去掉最大最小值的部门平均薪水

有员工薪资表t3_salary,包含员工ID(emp_id)&#xff0c;部门ID(depart_id)&#xff0c;薪水(salary),请计算去除最高最低薪资后的平均薪水&#xff1b;&#xff08;每个部门员工数不少于3人&#xff09; CREATE TABLE t3_salary (emp_id bigint,depart_id bigint,salary decima…

使用springCache实现缓存

简介 这个springCache貌似jdk8或者以上才可以 cache最好加在controller层,毕竟返回给前端的数据,在这一步才是最完整的,缓存controller的数据才有意义配置 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…

业务封装与映射 -- OTUk/ODUk/OPUk开销帧结构

开销是为了保证净荷正常、灵活传送所必须附加的供网络运行、管理和维护&#xff08;OAM&#xff09;使用的字节。 OTN电层开销包括OTUk开销、ODUk开销、OPUk开销、OTUCn开销、ODUCn开销、OPUCn开销和帧对齐开销。 SM开销属于OTU开销&#xff0c;占用3个字节&#xff1b;PM开销…

【HappyCoding 之前,如何做好需求分析?】

“代码没写完&#xff0c;哪有脸睡觉”&#xff1f;代码爱好者们如是说。在工作当中&#xff0c;开发者往往也要担任需求分析的角色&#xff0c;承担一些需求分析设计文档编写等工作&#xff0c;这对于一些刚入行的新手或是一些自我封闭的“代码高手”来说是比较头疼的&#xf…

用Python Turtle绘制天安门技术讲解

概述 Python的Turtle模块是一个简单的绘图库&#xff0c;它允许用户通过简单的命令控制一个小海龟在屏幕上移动&#xff0c;绘制出各种图形。本文将通过一个具体的示例——绘制简化版的天安门&#xff0c;来详细讲解如何使用Turtle模块。 环境准备 确保你的Python环境中已经…

【CF2021E】Digital Village(All Version)

题目 给你一张 n n n 个点 m m m 条边的无向图&#xff0c;有 p p p 个关键点。你需要选择 k k k 个点染黑&#xff0c;使得这 p p p 个关键点到这 k k k 个黑点的代价和最小。定义代价为两点之间边权最大的边的最小值。 你需要求出 k 1,2,…,n 的所有答案 E1 n,m,p&l…

OBOO鸥柏丨数字化展厅液晶拼接屏联动展馆触摸屏查询一体机信息化

在OBOO鸥柏精心雕琢的多媒体展厅展馆解决方案中&#xff0c;鸥柏液晶拼接屏的多屏联动互动技术犹如一条无形的数字科技纽带&#xff0c;OBOO鸥柏巧妙地将多台商用显示设备编织成一幅幅动态共生的视觉盛宴。鸥柏这项技术&#xff0c;不仅仅是简单的显示设备互联&#xff0c;鸥柏…

73.【C语言】C/C++的内存区域划分

1.内存里的几个区域 除了耳熟能详的栈区,堆区,静态区,还有内核空间,内存映射段,数据段,代码段 2.示意图 3.解释 栈区(stack area):局部变量,函数参数,返回数据,返回地址 内存映射段:将文件映射到内存 映射: 如果看过王爽老师的 《汇编语言 第四版》,其中写到了可以操作B800…

【可答疑】基于51单片机的倒车雷达测距(含仿真、代码、报告、演示视频等)

✨哈喽大家好&#xff0c;这里是每天一杯冰美式oh&#xff0c;985电子本硕&#xff0c;大厂嵌入式在职0.3年&#xff0c;业余时间做做单片机小项目&#xff0c;有需要也可以提供就业指导&#xff08;免费&#xff09;~ &#x1f431;‍&#x1f409;这是51单片机毕业设计100篇…

三、数据链路层(下)

目录 3.6以太网 以太网的分类 Mac地址 以太网数据格式 3.7互联网 数据是如何传输的&#xff1f; 3.8以太网、局域网、互联网的区别 总结&#xff1a; 3.9 vlan基本概念与基本原理 Vlan实现 划分 VLAN 例题 3.10广域网及相关协议 ppp协议 PPP协议所满足的要求 P…

【GitHub】上传文件到GitHub

参考视频&#xff1a;手把手教你在github上传文件_哔哩哔哩_bilibili 1.找到文件夹右键&#xff0c;选择open git bash here 2.完成指令 git initgit add *git commit -m "first commit"3.打开该文件夹&#xff0c;打开隐藏文件.git/config 编辑输入邮箱和GitHub用…

关于Qt音乐播放器进度条拖拽无用的问题解决方案

在使用Qt编写音乐播放器的时候&#xff0c;进度条关联播放音乐基本是必须的。那么在设计的过程中你可能会碰到一个奇怪的问题就是拖拽进度条的时候&#xff0c;可能会报错如下&#xff1a; 然后音乐就卡着不动了。。。 connect(ui->volume_toolButton,&VolumeToolBtn::…

AI大模型,但是在卫星

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 AI圈又发生了啥新鲜事&#xff1f; 国星宇航实现全球首次卫星在轨AI大模型技术验证 国星宇航成功完成了全球首次卫星在轨运行AI大模型技术验证&#xff0c;验证了AI大模型在太空中的空间适应性和算力…

解决ERR_PROXY_CONNECTION_FAILED

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 错误描述 电脑无法正常上网&#xff0c;报错信息如下&#xff1a;ERR_PROXY_CONNECTION_FAILED&#xff1b;图示如下&#xff1a; 解决方案 请按如下步骤和方式解决该问题…

Linux 系统成为隐秘“Perfctl”加密挖矿恶意软件的目标

Aqua Security 的研究人员上周透露&#xff0c;数以千计的 Linux 系统可能感染了极难追踪且持久的“perfctl”&#xff08;或“ perfcc ”&#xff09;加密挖掘恶意软件&#xff0c;许多其他系统仍然面临被入侵的风险。 在观察到的所有攻击中&#xff0c;恶意软件都被用来运行…

C语言入门指南:为大一新生准备

C语言入门指南&#xff1a;为大一新生准备 C语言是许多编程语言的基础&#xff0c;许多现代编程语言&#xff08;如C、Java、Rust等&#xff09;都从C语言中汲取了灵感。因此&#xff0c;学习C语言不仅能帮助你掌握编程的基本概念&#xff0c;还能为学习其他编程语言打下坚实的…

ThinkBook 16+ 锐龙6800h 安装ubuntu键盘失灵

问题&#xff1a;在ThinkBook 16 锐龙6800h 安装ubuntu18.04 出现笔记本键盘按下延迟非常高&#xff0c;输出卡死的情况&#xff0c;但是外接键盘可以正常使用 解决&#xff1a;更新内核 1、进入 https://kernel.ubuntu.com/~kernel-ppa/mainline/ 下载所需内核版本&#x…

Array类、引用类型

前面我们对数组的增加,删除,查找,更改都需要进行循环遍历,非常的麻烦。C#系统为我们提供了Array类,在这个类中定义了许多对数组进行操作的方法,我们可以直接用,从而提高效率。 索引查找: int[] a = { 1, 2, 3, 4, 3 }; int b=Array.IndexOf(a, 3);//第一个参数为数组…

判断是否为二叉排序树(二叉搜索树,二叉查找树)

1.判断给定的二叉树是否为二叉排序树&#xff0c;如果是返回1&#xff0c;不是返回0。 思想&#xff1a; 二叉树是左子树<根<右子树。中序遍历是递增有序&#xff0c;可以通过比较当前结点与前驱关系来进行判断。 代码&#xff1a; //pre为全局变量&#xff0c;保存当…