文心一言 VS 讯飞星火 VS chatgpt (357)-- 算法导论24.2 3题

三、上面描述的 PERT 图的公式有一点不太自然。在一个更自然的结构下,图中的结点代表要执行的工作,边代表工作之间的次序限制,即边 (u,v) 表示工作 u 必须在工作 v 之前执行。在这种结构的图中,我们将权重赋给结点,而不是边。请修改 DAG-SHORTEST-PATHS 过程,使得其可以在线性时间内找出这种有向无环图中一条最长的路径。如果要写代码,请用go语言。

文心一言:

在处理有向无环图(DAG)并希望找到最长路径时,如果权重被赋给节点而不是边,并且我们关注的是从源节点到任意其他节点的最长路径,我们可以使用动态规划的方法来解决这个问题。然而,如果目标是找到图中任意两点之间的最长路径,问题将变得复杂且不一定存在多项式时间解决方案(特别是如果图中存在环,尽管这里我们处理的是DAG)。

对于DAG中的最长路径问题(权重在节点上),一个常见的方法是使用拓扑排序和动态规划。我们将基于这个思路来实现Go代码。

步骤 1: 拓扑排序

首先,我们需要对图进行拓扑排序,以确保在处理每个节点时,其所有前驱节点都已经被处理。

步骤 2: 动态规划计算最长路径

在拓扑排序的基础上,我们可以从源节点开始,逐步计算到达每个节点的最长路径。

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

package main

import (
    "container/heap"
    "fmt"
)

type Node int

type Graph map[Node][]Node

type IntHeap []int

func (h IntHeap) Len() int           {
    return len(h) }
func (h IntHeap) Less(i, j int) bool {
    return h[i] > h[j] } // 最大堆
func (h IntHeap) Swap(i, j int)      {
    h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{
   }) {
   
    *h = append(*h, x.(int))
}

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

func topologicalSort(g Graph) ([]Node, error) {
   
    inDegree := make(map[Node]int)
    for u := range g {
   
        inDegree[u] = 0
    }
    for u, neighbors := range g {
   
        for _, v := range neighbors {
   
            inDegree[v]++
        }
    }

    queue := &IntHeap{
   }
    heap.Init(queue)
    for u, degree := range inDegree {
   
        if degree == 0 {
   
            heap.Push(queue, int(u))
        }
    }

    var sorted []Node
    for queue.Len() > 0 {
   
        u := Node(heap.Pop(queue).(int))
        sorted = append(sorted, u)
        for _, v := range g[u] {
   
            inDegree[v]--
            if inDegree[v] == 0 {
   
                heap.Push(queue, int(v))
            }
        }
    }

    if len(sorted) != len(g) {
   
        return nil, fmt.Errorf("graph has cycles")
    }
    return sorted, nil
}

func longestPath(g Graph, nodeWeights map[Node]int) (map[Node]int, error) {
   
    sorted, err := topologicalSort(g)
    if err != nil {
   
        return nil, err
    }

    dp := make(map[Node]int)
    for _, node := range sorted {
   
        dp[node] = nodeWeights[node]
        for _, neighbor := range g[node] {
   
            if val, ok := dp[neighbor]; ok {
   
                dp[node] = max(dp[node], val+nodeWeights[node])
            }
        }
    }

    return dp, nil
}

func max(a, b int) int {
   
    if a > b {
   
        return a
    }
    return b
}

func main() {
   
    g := Graph{
   
        0: []Node{
   1, 2},
        1: []Node{
   3},
        2: []Node{
   3},
        3: nil,
    }
    nodeWeights := map[Node]int{
   
        0: 2,
        1: 3,
        2: 5,
        3: 0,
    }

    longest, err := longestPath(g, nodeWeights)
    if err != nil {
   
        fmt.Println("Error:", err)
        return
    }

    fmt.Println("Longest Path Values:", longest)
}

注意:

  • longestPath函数中,dp[node]存储的是从源节点(这里假设为所有节点可达的起始点)到node的最长路径长度。
  • 我们需要确保图是无环的,这通过拓扑排序来检查。
  • max函数用于比较两个整数并返回较大的那个。
  • 这个实现假设图中至少有一个节点,并且所有节点都是可达的(从源节点出发)。在实际应用中,可能需要添加额外的逻辑来处理特殊情况。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

讯飞星火:

为了在有向无环图(DAG)中找到最长路径,我们可以使用拓扑排序算法。首先,我们需要对图进行拓扑排序,然后按照拓扑排序的顺序遍历结点,同时更新每个结点的最长路径。以下是使用 Go 语言实现的代码:

package main

import (
	"fmt"
)

type Edge struct {
   
	To   int
	Cost int
}

func longestPath(n int, edges [][]Edge) []int {
   
	// 初始化邻接表
	adjList := make([][]Edge, n)
	for _, edge := range edges {
   
		u, v, cost := edge[0].To, edge[1].To, edge[1].Cost
		adjList[u] = append(adjList[u], Edge{
   v, cost})
	}

	// 拓扑排序
	var topoSort func(int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

福大大架构师每日一题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值