加油站变型算法的验证

时间:2015-11-20 06:29:01

标签: algorithm dynamic-programming greedy

enter image description here

我正在研究这个问题,我认为这是加油站问题的一个变种。结果,我使用Greedy算法来解决这个问题。我想问一下是否有人帮助我指出我的算法是否正确,谢谢。

我的算法

  var x = input.distance, cost = input.cost, c = input.travelDistance, price = [Number.POSITIVE_INFINITY];
  var result = [];

  var lastFill = 0, tempMinIndex = 0, totalCost = 0;

  for(var i=1; i<x.length; i++) {
    var d = x[i] - x[lastFill];
    if(d > c){ //car can not travel to this shop, has to decide which shop to refill in the previous possible shops
      result.push(tempMinIndex);
      lastFill = tempMinIndex;
      totalCost += price[tempMinIndex];
      tempMinIndex = i;
    }
    //calculate price
    price[i] = d/c * cost[i];
    if(price[i] <= price[tempMinIndex])
      tempMinIndex = i;
  }

  //add last station to the list and the total cost
  if(lastFill != x.length - 1){
    result.push(x.length - 1);
    totalCost += price[price.length-1];
  }

您可以在此链接上试用算法 https://drive.google.com/file/d/0B4sd8MQwTpVnMXdCRU0xZFlVRlk/view?usp=sharing

1 个答案:

答案 0 :(得分:1)

首先,关于你的解决方案。

即使在最简单的输入上,也有一个错误。当你确定距离变得太远并且你应该在之前的某个时刻完成时,你不会更新距离和加油站收取你应该更多的费用。修复很简单:

if(d > c){ 
//car can not travel to this shop, has to decide which shop to refill
//in the previous possible shops
      result.push(tempMinIndex);
      lastFill = tempMinIndex;
      totalCost += price[tempMinIndex];
      tempMinIndex = i;
      // Fix: update distance
      var d = x[i] - x[lastFill];
    }

即使使用此修复程序,您的算法也会在某些输入数据上失败,如下所示:

0 10 20 30
0 20 30 50
30

它应该重新加注每种汽油以降低成本,但它只是填补了最后一种。

经过一番研究,我想出了解决方案。我将尝试尽可能简单地解释它,使其与语言无关。

  1. 对于每个加油站G,我们将计算最便宜的加油方式。我们将以递归方式执行此操作:对于每个加油站,我们可以找到i所有加油站G。对于每个i计数最便宜的填充可能,并总结在G给定汽油剩余时的填充成本。开始加油站成本为0.更正式: MinGasStation function definition

    Cost function definition

    BestCost function definition

    可以从输入数据中检索

    CostOfFilling(x)CapacityPosition(x)

    因此,问题的答案只是BestCost(LastGasStation)

    1. 现在,使用javascript解决方案可以让事情变得更加清晰。

      function calculate(input)
      {
          // Array for keeping calculated values of cheapest filling at each station
          best = [];
          var x = input.distance;
          var cost = input.cost;
          var capacity = input.travelDistance;
      
          // Array initialization
          best.push(0);
          for (var i = 0; i < x.length - 1; i++)
          {
              best.push(-1);
          }
      
          var answer = findBest(x, cost, capacity, x.length - 1);
          return answer;
      }
      
      // Implementation of BestCost function
      var findBest = function(distances, costs, capacity, distanceIndex)
      {
          // Return value if it's already have been calculated
          if (best[distanceIndex] != -1)
          {
              return best[distanceIndex];
          }
          // Find cheapest way to fill by iterating on every available gas station
          var minDistanceIndex = findMinDistance(capacity, distances, distanceIndex);
          var answer = findBest(distances, costs, capacity, minDistanceIndex) + 
              calculateCost(distances, costs, capacity, minDistanceIndex, distanceIndex);
          for (var i = minDistanceIndex + 1; i < distanceIndex; i++)
          {
              var newAnswer = findBest(distances, costs, capacity, i) + 
              calculateCost(distances, costs, capacity, i, distanceIndex);
              if (newAnswer < answer)
              {
                  answer = newAnswer;
              }
          }
          // Save best result
          best[distanceIndex] = answer;
          return answer;
      }
      
      // Implementation of MinGasStation function
      function findMinDistance(capacity, distances, distanceIndex)
      {
          for (var i = 0; i < distances.length; i++)
          {
              if (distances[distanceIndex] - distances[i] <= capacity)
              {
                  return i;
              }
          }
      }
      
      // Implementation of Cost function
      function calculateCost(distances, costs, capacity, a, b)
      {
          var distance = distances[b] - distances[a];
          return costs[b] * (distance / capacity);
      }
      

      包含代码的完整可用的html页面here