【问题标题】:Dynamic Programming Algorithm similar to Knapsack Java Code类似于背包Java代码的动态编程算法
【发布时间】:2016-06-10 08:37:09
【问题描述】:

任务关键型生产系统有 n 个阶段,必须按顺序执行;阶段 i 由机器 M_i 执行。

每台机器 M_i 具有可靠运行的概率 r_i 和失败的概率 1-r_i(并且故障是独立的)。因此,如果我们用一台机器来实现每个阶段,整个系统工作的概率是 r_1,r_2,...,r_n。为了提高这种概率,我们通过拥有执行阶段 i 的机器 M_i 的 m_i 个副本来添加冗余。

所有m_i个副本同时失败的概率只有(1-r_i)^(m_i),所以第i阶段正确完成的概率是1-(1-r_i)^(mi)和整个系统工作是 prod(i=1,n){1-(1-r_i)^(m_i)}。

每台机器 M_i 都有成本 c_i,购买机器有总预算 B。 (假设 B 和 c_i 是正整数。)在给定概率 r_1,...,r_n,成本 c_1,...,c_n 和预算 B 的情况下,用 java 代码编写算法,找到冗余 m_1,.. .,m_n 在可用预算范围内并且最大化系统正常工作的概率(确定可实现的最大可靠性)。此外,显示每种类型有多少机器在预算范围内实现了该可靠性。

所以我读了一个文件,其中给出了允许的总预算,然后是机器的数量,然后是我读到的每台机器的成本和可靠性。我将成本和可靠性存储到两个链表中(不确定这是否最好)。

  try {
            BufferedReader newFileBuffer = new BufferedReader(new     FileReader(inputFile));
            budget = Integer.parseInt(newFileBuffer.readLine()); 
            numberOfMachines = Integer.parseInt(newFileBuffer.readLine()); 
            while ((fileLine  = newFileBuffer.readLine()) != null) 
            {       
                line = fileLine.split(" ");

                try 
                {
                    cost.add(Integer.parseInt(line[0]));
                    totalCostOfOneEach += Integer.parseInt(line[0]); 
                    reliability.add(Float.parseFloat(line[1]));
                } catch (NumberFormatException nfe) {};

            }
            newFileBuffer.close();
        } catch (Exception e) 
        {
            e.printStackTrace();
        }

从那里我知道每台机器必须使用一次,所以我将预算减去每台机器的总成本(totalCostOfOneEach),如果你愿意,这会给我剩余的预算或冗余预算。

bRedundent = (budget - totalCostOfOneEach);

现在是我卡住的地方,我不知道要循环什么来找到解决方案。我已经研究并发现了这个solution,但我不明白这一行

Pr(b,j)=max{Pr(b-c_j*k, j-1)*(1-(1-r_j)^k}

所以我所知道的是我创建了一个双精度数组,并且我将数组初始化为:

double[][] finalRel = new double[numberOfMachines][bRedundent]; 
for (int j = 0; j < numberOfMachines; j++)
{
    finalRel[0][j] = 0; 
}

for (int b = 1; b < budget; b++)
{
    finalRel[b][1] = reliability.get(0); 
}

现在是我卡住的地方,我相信我应该循环计算机器的数量,然后是成本,但这不起作用,我知道我需要以某种方式合并预算。所以这就是我目前拥有的根本不起作用的东西:

for (int i = 1; i < numberOfMachines; i++)
{
    for (int c = cost.get(i); c < budget; c++)
    {
        finalRel[i][c] = Math.min(finalRel[i-1][c], finalRel[i-1][c - cost.get(numberOfMachines)]*(l));
    }   
} 

我知道子问题表示为 finalRel[i, b],机器 1, 2, 的最可靠配置。 . . , i(每台机器至少一台)在预算范围内可用 b。所需的答案将是 finalRel[n, B]。

如果我们在预算范围内重复发生,我们返回可靠性 0(意味着不可能)。如果我们超出预算(b = 0),但仍需要购买机器(i > 0),我们返回 0(假设所有 ci > 0)。如果 i = 0,我们没有必须购买的机器,因此可靠性为 1(如果为 0,那么一切都会乘以 0,这不好)。如果剩余预算(b > 0)和剩余机器要购买(i > 0),我们尝试购买类型 i 机器的所有可能性 m - 我们必须至少购买 m ≥ 1,并且最多 m ≤ b ≤ floor(b/c_i) ≤ b ≤ B,其中。在每种情况下,剩余预算将为 b - m · c_i。机器的最佳可靠性 1, . . . , i - 1 将是 REL[i - 1, b - m · ci],需要乘以 M_i 的 m 个副本的贡献,(1 - (1 - ri)^m) 或汇总here .

我意识到这有很多信息,但我已经被困了一段时间,所以任何帮助表示感谢。

【问题讨论】:

    标签: java algorithm iteration dynamic-programming knapsack-problem


    【解决方案1】:

    您可以使用比这更简单的循环。对于i = 0, ..., nb = 0, ..., B,我们让R(i, b) 是从阶段1 到阶段i 给定预算B 的子管道的最大可靠性。基本情况是

    For b = 0, ..., B,
      R(0, b) = 1,
    

    因为空管道永远不会失败并且不花费任何费用。此后我们有了链接的重复,为了清楚起见,我稍微重写了:

    For i = 1, ..., n,
      For b = 0, ..., B,
        R(i, b) = max {R(i-1, b - k*c_i) * (1 - (1-r_i)^k)
                       for k = 1, ..., floor(b/c_i)},
    

    其中k 是我们正在考虑购买的阶段i 机器的数量(定义0^0 = 1 以防机器完全可靠;您应该自己计算功率,然后将强度降低为乘法,这解决了这个问题并提高了性能)。因素(1 - (1-r_i)^k)ik 机器的平台的可靠性。系数R(i-1, b - k*c_i) 是给定剩余预算的前阶段的最大可靠性。限制floor(b/c_i) 是总成本最高为b 的阶段i 机器的最大数量。

    【讨论】:

    • 我不明白这一行:R(i, b) = max{R(i-1, b - k*c_i) * (1 - (1-r_i)^k) for k = 0, ..., floor(b/c_i)} 这假设是如何工作的,你在双数组和定义 k 的楼层循环之间取最大值,但我们正在尝试在 max 函数中定义之前使用它?如果假设 for 循环包含在 max 函数中,我看不到它将如何返回双精度数组?抱歉,我正在为这个逻辑而苦苦挣扎。
    • 在java中实现这个的方法是使用ImmutableSet.Builder吗? docs.guava-libraries.googlecode.com/git/javadoc/com/google/…
    • @BillLogger 不,用循环替换它。
    • 我无法在评论中添加新行,所以格式很丑。
    • 这是我最初的想法,但仍然无法正常工作或我的预期。不知道我做错了什么:numberOfMachines = 8; budget = 1000; for (int i = 1; i &lt; numberOfMachines; i++) { for (int b = 0; b &lt; budget; b++) { for (int k = 0; k &lt; (Math.floor(b/cost.get(i))); k++) { finalRel[i][b] = Math.max(finalRel[i-1][b], (finalRel[i-1][b-cost.get(i)*k] * (1-Math.pow((1-reliability.get(i)),k)))); } } } double x = finalRel[numberOfMachines-1][budget-1]; System.out.println(x); } }
    猜你喜欢
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2021-05-04
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多