最小路径开销

原文地址 http://www.daileinote.com/computer/math/0f

最小开销路径(Min Cost Path)(MCP),给出一个开销矩阵cost,求得从cost[x][y] 到 cost[i][j] 的最小开销。比如下图

从 (0,0) 到 (2,2) 的最小开销为 8 (1 + 2 + 2 + 3)

想要到达 (m, n),必须经过 (m-1, n-1),(m-1, n),(m, n-1) 其中一个, 所以 minCost(m, n) = min (minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1)) + cost[m][n]

下面是没有解决重叠子问题的例子

#include <stdio.h>
#include <string.h>
#define dl_max(x,y) ((x) > (y) ? (x) : (y))
#define MAX_COST 1024   // 这里定义一个上限
int dl_min(int x, int y, int z) { if (x < y) return x < z ? x : z; else return y < z ? y : z;}
int min_cost(int cost[3][3], int m, int n)
{
    if (m < 0 || n < 0)
        return MAX_COST;

    if (m == 0 && n == 0)
        return cost[m][n];

    return cost[m][n] + dl_min(min_cost(cost, m-1,n), min_cost(cost, m,n-1), min_cost(cost, m-1,n-1));
}

int main()
{
    int cost[3][3] = {
        {1, 2, 3},
        {4, 8, 2},
        {1, 5, 3}
    };

    printf("min cost: %d\n", min_cost(cost, 2, 2));
}
                                    mC(2, 2)
                          /            |           \
                         /             |            \             
                 mC(1, 1)           mC(1, 2)             mC(2, 1)
              /     |     \       /     |     \           /     |     \ 
             /      |      \     /      |      \         /      |       \
       mC(0,0) mC(0,1) mC(1,0) mC(0,1) mC(0,2) mC(1,1) mC(1,0) mC(1,1) mC(2,0)

上面有很多重复计算的问题,跟其他动态规划问题一样,这里满足 最优子结构 和 重叠子问题,可以构建 arr[][]解决

#include <stdio.h>
#include <string.h>
int dl_min(int x, int y, int z) { if (x < y) return x < z ? x : z; else return y < z ? y : z;}
int min_cost(int cost[3][3], int m, int n)
{
    int     i,j,sum[3][3];

    sum[0][0] = cost[0][0];

    //计算第一列
    for (i = 1; i <= m; i++)
        sum[i][0] = sum[i-1][0] + cost[i][0];
    
    //计算第一行
    for (i = 1; i <=n; i++)
        sum[0][i] = sum[0][i-1] + cost[0][i];

    for (i = 1; i <= m; i++) {
        for (j = 1; j <= n; j++) {
            sum[i][j] = cost[i][j] + dl_min(sum[i-1][j], sum[i][j-1], sum[i-1][j-1]);
        }
    }

    return sum[m][n];
}

int main()
{
    int cost[3][3] = {
        {1, 2, 3},
        {4, 8, 2},
        {1, 5, 3}
    };
    printf("min cost: %d\n", min_cost(cost, 2, 2));
}

时间复杂度为 O(mn)

原文地址 http://www.daileinote.com/computer/math/0f​​​​​​​

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是网络拓扑和链路开销表格: | | x | a | b | c | d | e | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | x | 0 | 5 | 2 | 4 |inf |inf | | a |inf | 0 |inf |inf | 11 |inf | | b |inf | 3 | 0 |inf | 6 |inf | | c |inf |inf | 4 | 0 |inf | 5 | | d |inf |inf |inf |inf | 0 |inf | | e |inf |inf |inf |inf | 5 | 0 | 首先将起点x到各节点的距离初始化为表格中的第一行。然后选择离起点最近的节点b,更新与b相邻的节点(a和c)的距离。此时,x到a的距离更新为5(原来是无穷大),x到c的距离更新为2(原来是4)。更新后的表格如下: | | x | a | b | c | d | e | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | x | 0 | 5 | 2 | 4 |inf |inf | | a | 5 | 0 |inf | 6 | 11 |inf | | b |inf | 3 | 0 | 4 | 6 |inf | | c | 2 | 7 | 4 | 0 |inf | 5 | | d |inf |inf |inf |inf | 0 |inf | | e |inf |inf |inf |inf | 5 | 0 | 接下来选择离起点最近的节点c,更新与c相邻的节点(b和e)的距离。此时,x到b的距离更新为4(原来是2),x到e的距离更新为7(原来是无穷大)。更新后的表格如下: | | x | a | b | c | d | e | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | x | 0 | 5 | 2 | 4 |inf | 7 | | a | 5 | 0 |inf | 6 | 11 | 12 | | b | 4 | 3 | 0 | 4 | 6 | 9 | | c | 2 | 7 | 4 | 0 |inf | 5 | | d |inf |inf |inf |inf | 0 |inf | | e | 9 |inf | 7 | 11 | 5 | 0 | 然后选择离起点最近的节点b,更新与b相邻的节点(a和d)的距离。此时,x到a的距离不变,x到d的距离更新为10(原来是无穷大)。更新后的表格如下: | | x | a | b | c | d | e | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | x | 0 | 5 | 2 | 4 | 10 | 7 | | a | 5 | 0 | 8 | 6 | 11 | 12 | | b | 4 | 3 | 0 | 4 | 6 | 9 | | c | 2 | 7 | 4 | 0 | inf| 5 | | d | 14 | 9 | 11 | 13 | 0 |inf | | e | 9 |inf | 7 | 11 | 5 | 0 | 最后选择离起点最近的节点a,更新与a相邻的节点d的距离。此时,x到d的距离不变。更新后的表格如下: | | x | a | b | c | d | e | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | x | 0 | 5 | 2 | 4 | 10 | 7 | | a | 5 | 0 | 8 | 6 | 11 | 12 | | b | 4 | 3 | 0 | 4 | 6 | 9 | | c | 2 | 7 | 4 | 0 | 15 | 5 | | d | 14 | 9 | 11 | 13 | 0 |inf | | e | 9 | 14 | 7 | 11 | 5 | 0 | 因此,从x到所有其他节点的最短路径如下: - x到a的最短路径为5,路径为x->b->a。 - x到b的最短路径为2,路径为x->b。 - x到c的最短路径为4,路径为x->c。 - x到d的最短路径为10,路径为x->b->a->d。 - x到e的最短路径为7,路径为x->e。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值