【问题标题】:A variation on the Dijkstra shortest path algorithmDijkstra 最短路径算法的一种变体
【发布时间】:2023-03-23 07:42:01
【问题描述】:

我被这个问题困住了(我的解决方案太慢了)。我将描述问题然后我的解决方案。

问题: 给定N 站,每个在数轴上的x_i 位置,我们想将机器人从第一个站移动到最后一个站(站按非排序- 以最低的货币成本减少x_i 订单)。我们有一个机器人,它以最大充电电池开始,具有K(不一定是整数)功率单位,并且可以移动每单位功率的E(不一定是整数)长度单位。在第一站和最后一站之间的任何站,我们都可以充电。每个站收取相同的统一费率F 美元开始充电,加上每单位电量补充c_i 美元。机器人ONLY可以充电,如果当时的电量在K/2或以下OR不充电就不能到达下一站;机器人每次充电,都要充电到 100%(即K)。

我的解决方案:我很确定这是最短路径问题的一种变体,但我们正在优化货币成本。我正在运行 Dijkstra SSSP。但是,对于每个州,我们都需要跟踪货币成本和剩余能源,因为通过在便宜的充电站充电而提前增加成本可能比把钱存到最后更好。因此,我没有继续维护cost[i]=cheapest known way to get to station i,而是维护cost[i][energy]=cheapest known way to get to station i with a certain energy。在优先级队列中,我仅按成本对状态进行排序,因为我不确定是否有办法为剩余成本和剩余能量创建启发式方法。这个算法在某些测试用例上确实很慢,因为如果E 和K 很大,那么每个站点都可能会到达它前面的每个站点,从而创建一个庞大的图形。我想我必须修剪搜索边界,但我不确定如何。有什么想法吗?

【问题讨论】:

    标签: algorithm dijkstra shortest-path


    【解决方案1】:

    这听起来更像是动态编程的工作,而不是 Dijkstra 的工作。车站i 的最佳成本与您在到达那里之前所做的选择无关。

    通过车站向后移动。对于车站i,考虑您可以从那里到达的所有车站j > i(您已经计算了它们的最佳成本)。从中选择最佳的。

    在伪代码中:

    opt[N-1] = 0                                        // cost of the last station is 0
    for i = N-2 down to 0                               // loop backwards over the stations
        opt[i] = infinity
        for j = i+1 to N-1 where (x_j - x_i) * E <= K   // loop over all next stations that can be reached without a flat battery
            energyToJ = (x_j - x_i) * E
            if (energyToJ >= K/2                        // we are allowed to recharge
              or j == N-1                               //  or we cannot reach the next station because there is none
              or x_{j+1} - x_i) * E > K)                //   or because it is too far
                costJ = F + energyToJ * c_j + opt[j]    // total cost via j is cost to j + cost from j
                if (costJ < opt[i])                     // keep track of the optimal cost
                    opt[i] = costJ                      
    
    return opt[0]
    

    编辑

    由于动态编程不适合您,因此我将使用 Dijkstra 的方法来处理它:

    从i 站,您可以直接移动到每个站 j,其中一个满足以下条件:

    • K/2 &lt;= x_j - x_i &lt;= K
    • 0 &lt;= x_j - x_i &lt; K/2 并且没有 j' &gt; j 对应的 x_j' - x_i &lt;= K

    使用N 顶点创建一个图形,每个站点一个。当且仅当上述两个条件之一成立时,从站 i 到站 j 存在有向边 e_ij。 e_ij的重量,简直就是那里充值的成本,也就是F + (x_j - x_i) * c_j。

    您现在只需在此图表上运行 Dijkstra 即可找到到达终点站的最经济的方式。我们不需要同时记录距离和金钱的原因是距离已经编码在图的结构中:图的边缘恰好是从一个站点到另一个站点的所有可能移动另一个。

    【讨论】:

    • 我们还没有在课堂上介绍动态编程,这是我们散列/图/数论单元的一部分。讲师还明确提到了优先队列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多