加油站动态规划

2023-12-22

您和您的朋友正开车前往蒂华纳度春假。您正在为旅行省钱,因此您希望尽量减少途中的汽油费用。为了最大限度地减少您的天然气成本,您和您的朋友整理了以下信息。首先,您的汽车可以通过一箱油可靠地行驶 m 英里(但不能再远)。您的一位朋友从网上挖掘了加油站数据,并绘制了您路线上的每个加油站以及该加油站的汽油价格。具体来说,他们创建了一个从最近到最远的 n+1 个加油站价格列表以及两个相邻加油站之间的 n 距离列表。塔科马是 0 号加油站,蒂华纳是 n 号加油站。为了方便起见,他们将汽油成本转换为汽车行驶每英里的价格。此外,还计算了两个相邻加油站之间的英里距离。您将在加满油的情况下开始您的旅程,当您到达蒂华纳时,您将为返程加满油。您需要确定在哪些加油站停车,以最大限度地减少旅途中的汽油成本。

输入示例:

价格(美分/英里) [12,14,21,14,17,22,11,16,17,12,30,25,27,24,22,15,24,23,15,21]

距离(英里) [31,42,31,33,12,34,55,25,34,64,24,13,52,33,23,64,43,25,15]

您的汽车加一箱油可以行驶 170 英里。

我的输出:

此次旅行的最低费用为:$117.35

加油站停靠:[1, 6, 9, 13, 17, 19]

我已经解决了这个问题,但我不确定我是否以正确的方式完成了它。如果错误的话,有人可以给我一些建议或指出正确的方向吗?先感谢您。

public class GasStation {

/** An array of gas prices.*/
private int[] myPrice;
/** An array of distance between two adjacent gas station.*/
private int[] myDistance;
/** Car's tank capacity.*/
private int myCapacity;
/** List of gas stations to stop at to minimize the cost.*/
private List<Integer> myGasStations;


/**
 * A constructor that takes in a price list, distance list, and the car's tank capacity.
 * @param thePrice - price list
 * @param theDistance - distance list
 * @param theCapacity - the car's capacity
 */
public GasStation(final int[] thePrice, final int[] theDistance,
        final int theCapacity) {
    myPrice = thePrice;
    myDistance = theDistance;
    myCapacity = theCapacity;
    myGasStations = new ArrayList<>();
}


/**
 * Calculate for the minimum cost for your trip.
 * @return minimum cost
 */
public int calculateMinCost() {

    int lenP = myPrice.length;
    int lenD = myDistance.length;
    if (lenP == 0 || lenD == 0 || myCapacity == 0) return 0;

    // gas station -> another gas station (moves) 
    Map<Integer, Integer> gasD = new HashMap<>();
    int[] D = new int[lenD + 1];
    D[0] = 0;

    // calculate the total distance 
    for (int i = 0; i < lenD; i++) {
        D[i + 1] = D[i] + myDistance[i];
    }

    int len = D.length;
    for (int i = 1; i < len - 1; i++) {
        int j = len - 1;
        while (D[j] - D[i] >= myCapacity) {
            j--;
        }
        gasD.put(i, j - i);
    }

    int min = Integer.MAX_VALUE;

    for (int i = 1; i < len; i++) {
        int temp = 0;
        int cur = i;
        List<Integer> tempList = new ArrayList<>();
        if (D[i] <= myCapacity) {
            temp = D[cur] * myPrice[cur];
            tempList.add(cur);
            int next = gasD.get(cur) + cur;
            while (next < len) {
                temp += (D[next] - D[cur]) * myPrice[next];
                cur = next;
                tempList.add(cur);
                if (gasD.containsKey(cur)) next = gasD.get(cur) + cur;
                else break;
            }

            if (temp < min) {
                min = temp;
                myGasStations = tempList;
            }

        }
    }


    return min;
}

/**
 * Get gas stations to stop at.
 * @return a list of gas stations to stop at
 */
public List<Integer> getGasStations() {
    return myGasStations;
}

}


让最小的补充成本为station i记为cost[i]

给定问题陈述,如何表达该成本?
我们知道每次下一次补充都必须在170 miles远离最后一次补充,
因此最小成本可以表示为:

cost[i] = MIN { cost[j] + price[i] * distance_from_i_to_j } for every j such that distance(i,j) <= 170 mi

带底座cost[0] = 0如果我们不考虑全罐成本station 0,否则基本情况是cost[0]= 170 * price[0]

我假设我们不考虑全罐成本station 0,并且在最后一点不需要补充,即station 19

通过查看上面定义的递归关系,我们可以很容易地注意到同一子问题被多次调用,这意味着我们可以利用动态规划解决方案来避免可能的指数运行时间。

另请注意,由于我们不需要在station 19,我们应该计算加油站的加油费用1通过18仅,即cost[1], cost[2], .., cost[18]。这样做之后,问题的答案将是MIN { cost[14], cost[15], cost[16], cost[17], cost[18] }因为唯一的车站位于 170 英里以内station 19是站14,15,16,17,18这样我们就可以到达车站19在这 5 个加油站之一进行加油。

当我们定义了上述与基本情况的递归关系后,我们可以通过以下方式将其转换为循环:

int price[] =  {12,14,21,14,17,22,11,16,17,12,30,25,27,24,22,15,24,23,15,21}; //total 20 stations

int distance[] = {31,42,31,33,12,34,55,25,34,64,24,13,52,33,23,64,43,25,15};  //total 19 distances      

int N=19;
int[] cost = new int[N];    
int[] parent = new int[N]; //for backtracking

cost[0] = 0; //base case (assume that we don't need to fill gas on station 0)

int i,j,dist;
int maxroad = 170;

for(i=0; i<N; i++) //initialize backtracking array
    parent[i] = -1;


for(i=1; i<=N-1; i++) //for every station from 1 to 18
{

        int priceval = price[i]; //get price of station i               
        int min = Integer.MAX_VALUE;                
        dist = 0;            

        for(j=i-1; j>=0; j--) //for every station j within 170 away from station i
        {   
            dist += distance[j]; //distance[j] is distance from station j to station j+1
            if(dist>maxroad)
               break;   

            if((cost[j] + priceval*dist)<min) //pick MIN value defined in recurrence relation                       
               {
                min = cost[j] + priceval*dist;
                parent[i] = j;
               }

        }

        cost[i] = min;              

}


//after all costs from cost[1] up to cost[18] are found, we pick
//minimum cost among the stations within 170 miles away from station 19
//and show the stations we stopped at by backtracking from end to start

int startback=N-1;
int answer=Integer.MAX_VALUE;
i=N-1;
dist=distance[i];
while(dist<=maxroad && i>=0)
{
   if(cost[i]<answer)
      {
       answer = cost[i];
       startback=i;
      }  
   i--;
   dist += distance[i];
}


System.out.println("minimal cost=" + answer + "\nbacktrack:");

i=startback;
while(i>-1) //backtrack
{
    System.out.println(i + " ");
    i = parent[i];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

加油站动态规划 的相关文章

  • AbstractCollection 的 toArray 方法的实现中的代码有什么用

    public Object toArray Estimate size of array be prepared to see more or fewer elements Object r new Object size Iterator
  • 如何在不改变的情况下将字符串转换为字节?

    我需要一个解决方案将字符串转换为字节数组而不需要像这样进行更改 Input String s Test Output String s Test byte b Test 当我使用 s getBytes 那么回复是 B 428b76b8 但我
  • 无法让远程 EJB 与 Wildfly 上的 EJB 客户端 API 配合使用

    我目前正在努力让远程 EJB 调用在 wildfly 8 x 和 9 x 上工作 详细来说 它是关于使用 EJB 客户端 API 方法从独立客户端应用程序 而不是从另一个应用程序服务器 进行远程调用 远程命名方法适用于我 但不适用于我的场景
  • 使用 Java 检索 Window 进程的 CPU 使用率

    我正在寻找一个 Java 解决方案来查找 Windows 中正在运行的进程的 CPU 使用情况 查了一下网上 关于Java解决方案的信息似乎很少 请记住 我并不是要查找 JVM 的 CPU 使用情况 而是要查找当时在 Windows 中运行
  • JPA 为每个项目选择最新实例

    假设我有一个会议实体 每次会议都有一个与会者和一个会议日期 在我的会议表中 我可能为每个与会者举行多个会议 每个会议都有不同的日期 我需要一个 JPA 查询 该查询将为所有与会者仅选择最新的会议 例如 如果我的桌子看起来像这样 Meetin
  • UnsupportedOperationException:特权进程中不允许使用 WebView

    我在用android sharedUserId android uid system 在我的清单中获得一些不可避免的权利 从 HDMI 输入读取安卓盒子 http eweat manufacturer globalsources com s
  • 将位于 jar 中的文件读取为 java.io.File 对象

    与此类似的问题已发布 但似乎没有一个答案对我的情况有帮助 我正在编写一个程序包 它使用 Google 的凭据来获取 Google Apps 用户 为此 我使用服务帐户 因此为了检索凭据 我需要提供 除其他外 一个 p12 签名文件 Cred
  • Log4j 未使用属性文件找到自定义附加程序

    我正在尝试使用以下 XML 属性文件在 Eclipse 插件项目中配置 log4j 其中包括一个名为 EclipseLoggingAppender 的自定义附加程序
  • Tomcat JDBC 池中没有足够的空闲连接

    给定以下 Tomcat JDBC 连接设置
  • 先增后减的最长子序列

    我正在尝试解决以下问题 元素值先减小后增大的序列称为V序列 在有效的 V 序列中 递减臂中应至少有一个元素 递增臂中至少应有一个元素 例如 5 3 1 9 17 23 是一个有效的 V 序列 在递减臂中具有两个元素 即 5 和 3 在递增臂
  • 以最少插入次数将字符串转换为回文

    这是一个来自日常编码问题 https www dailycodingproblem com 给定一个字符串 找到可以通过插入来组成的回文数 单词中任何位置的字符数尽可能少 如果有 大于一个可以制作的最小长度的回文 返回 字典顺序最早的一个
  • Java中通过FTP创建文件夹层次结构

    Java 是否有现成的功能可以在远程 FTP 服务器上创建文件夹层次结构 Apache Commons 确实提供了 FTP 客户端 但我找不到创建目录层次结构的方法 它确实允许创建单个目录 makeDirectory 但创建整个路径似乎并不
  • 使用 eclipse 配置mockito 时出现问题。给出错误:java.lang.verifyError

    当我将我的mockito库添加到类路径中 并使用一个简单的mockito示例进行测试时 我尝试使用模拟对象为函数add返回错误的值 我得到java lang verifyerror 以下是用于测试的代码 后面是 logcat Test pu
  • Ubuntu 的打包 - Web 应用程序

    Web 应用程序没有与 C 或类似文件不同的 make 文件 但是 它需要放置在特定的目录中 例如 var www 我是 Linux 打包新手 所以我的问题是 如何将我的应用程序打包到 deb 中 以便在安装时将其放入 etc myprog
  • Restful WS 中的 WSDL 等价物是什么?如果没有,消费者如何生成所需的客户端类?

    比如说 我在java中有生产者 在 net中有消费者 生产者有一个方法 需要 员工作为方法参数并在数据库中创建员工 对于基于 SOAP 的 ws dot net 客户端将调用 WSDL 并创建存根 包括 dot net 中的员工数据表示 现
  • 将 @RequestLine 与 Feign 一起使用

    我有一个工作 Feign 接口定义为 FeignClient content link service public interface ContentLinkServiceClient RequestMapping method Requ
  • jsf 中的类型未找到属性

    我正在尝试调用 jsf 中使用 primefaces 的属性 但我有错误 500 在托管bean PersonelBean 类型上找不到 我正在使用 hibernate jsf 和 spring PersonelBean java Mana
  • JTable中动态加载大量数据

    这是我的问题 我目前有一个 JTable 其中包含 5 000 到超过 200 000 行 你知道我要说什么了 数据已经加载到内存中了 这不是问题 但是如何 我可以创建一个高效的 JTable 以便它只加载以下行 是可见的 并且任何事件仅作
  • 如何手动添加Android Studio依赖

    我多次尝试向我的项目添加依赖项 但每次都会出现错误 我想添加它们的依赖项是 de hdodenhof circleimageview 1 3 0 and com github bumptech glide glide 3 6 1 所以我想下
  • 用于从链表中删除元素的大 O 表示法[重复]

    这个问题在这里已经有答案了 我正在阅读有关链接列表的内容 我发现 从链表中删除所需的元素需要 O n 运行时间 其中 n 是元素的数量 列表中的元素 http www cs mcgill ca dprecup courses IntroCS

随机推荐

  • Asp.net mvc 3 - 自定义模型绑定

    我有一个这样的模型 public string Name get set public IEnumerable
  • 意外返回匿名结构

    我正在尝试实现一种方法 该方法返回基于原始结构的修改后的结构 例如 type Project struct Username string Id uint Alias string Data json RawMessage Scheme S
  • Assert() - 它有什么用?

    我不明白的目的assert 我的讲师说断言的目的是发现错误 例如 double divide int a int b assert 0 b return a b 上述断言有道理吗 我认为答案是肯定的 因为如果我的程序 不应该与0 数字零 但
  • Karate 0.9.5:无法在并行执行中获取命令行选项

    我正在尝试将我的项目更新到最新的空手道版本 0 9 5 除了并行执行之外 一切正常 它没有考虑我使用命令行 Dkarate options 运行的标签 这是我的 TestParallel java 类 public class QaaTes
  • 我们可以将 XPath 与 BeautifulSoup 一起使用吗?

    我正在使用 BeautifulSoup 抓取 URL 并使用以下代码来查找td其类别为的标签 empformbody import urllib import urllib2 from BeautifulSoup import Beauti
  • 如何获取点击列表项的上下文以在 Nativescript 中的另一个页面中显示详细信息

    我正在尝试创建一个列表视图来显示硬编码数组列表中的数据及其工作良好 但我需要使用户能够单击任何项 目以在另一个页面中显示该项目的详细信息 我该怎么做 我尝试创建另一个数组来获取详细信息 并使 BindingContext 及其工作正常 但在
  • 通过 hbase shell 的行键?

    我在用 scan table name COLUMNS gt column family column qualifier LIMIT gt 2 列出 hbase 表中的 2 行 但我想知道是否可以使用 hbase shell 实现以下目标
  • Outlook 电子邮件转 pdf 安全提示

    我有一个任务 需要创建一个将 Outlook 电子邮件转换为 pdf 的程序 这是我的代码 Microsoft Office Interop Outlook Application app new Microsoft Office Inte
  • Google Oauth 弹出取消回调

    使用 Google 身份服务 GSI 时 我可以显示一个弹出窗口 要求用户连接他们的 Google 帐户 这是有很好的文档记录的 并且它与以下代码配合得很好 const client window google accounts oauth
  • SpriteKit:无法更改联系人回调中的节点位置

    我有一个具有动态物理体的节点 我想让它静止并在与另一个物体接触时改变它的位置 我设法使用此问题中提供的解决方案使主体静态 Sprite Kit 断言失败 typeA b2 dynamicBody typeB b2 dynamicBody h
  • 收集 Shiny R 中的所有输入标签

    受到这个答案的启发 收集整个 Shiny 应用程序中的所有用户输入 https stackoverflow com questions 41031584 collect all user inputs throughout the shin
  • SQLite 的 Android 持久性替代方案

    Android 中除了 SQLite 之外还有其他替代方案可以在手机中保存数据吗 我正在寻找类似 iOS coredata 的东西或更简单的东西 如键值存储 如果我们需要将其嵌入到应用程序中 尺寸相对较小的东西也很棒 谢谢您的帮助 如果您只
  • 搜索排序列表? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 什么是搜索或操作排序的 Pythonic 方法sequence https docs python or
  • 丢失 UDP 数据包的可能性有多大?

    好的 我正在为网络课程编程 并且必须使用 UDP 在 Java 中实现一个项目 我们正在实现一个 HTTP 服务器和客户端以及一个以指定概率损坏数据包的 gremlin 功能 HTTP 服务器必须在应用层将大文件分成多个段 以便通过 UDP
  • 实体框架/LINQ to SQL 数据绑定是否使用反射?

    如果之前有人问过这个问题 请原谅我 我进行了搜索 但找不到任何具体回答这个问题的内容 但我很乐意被推荐 我正在查看实体框架和 LINQ to SQL 虽然我喜欢这些系统 当然还有 LINQ 集成 但我对数据绑定方面有点怀疑 我获取了查询结果
  • 如何在Cocos2d-X中交换CCSprite对象中的精灵

    我有一个从 CCSprite 继承的对象 我想从这个对象内部改变图像 如何在 Cocos2d X 中更改图像 精灵 而不创建新的 CCSprite 对象 谢谢 阿德里安 mySprite gt setTexture CCTextureCac
  • ThreadPoolExecutor:任务正在排队但未提交

    我们有一个场景 提交给 ThreadPoolExecutor 的任务长时间运行 当线程池启动时 我们以核心池大小 5 最大池大小 20 和队列大小 10 来启动它 在我们的应用程序中 大约有 10 个任务被提交 大多数时候 这些任务运行几分
  • opencv_createsamples:找不到命令

    每次我运行命令opencv createsamples 我遇到了这个错误 我知道我需要跑步opencv来自 src 但我不知道如何完全做到这一点 有人可以给我一个详细而简单的解释 说明我将如何解决这个问题吗 None
  • 将帮助库移至其他位置

    我有一个 SSD 作为系统驱动器 C 它是一个真正的救星 但是这里的可用空间非常有价值 所以我希望将非重要文件远离此驱动器 主要磁盘之一 eater is the VisualStudio 帮助库在本地模式下使用 我在网上搜索过 但没有运气
  • 加油站动态规划

    您和您的朋友正开车前往蒂华纳度春假 您正在为旅行省钱 因此您希望尽量减少途中的汽油费用 为了最大限度地减少您的天然气成本 您和您的朋友整理了以下信息 首先 您的汽车可以通过一箱油可靠地行驶 m 英里 但不能再远 您的一位朋友从网上挖掘了加油