查找最低服务器停机总时间

时间:2015-12-25 08:35:45

标签: java arrays algorithm data-structures

您有一个数组,代表一系列服务器的“停机成本”。您只能访问该行两端的服务器(即您只能获得第一个服务器或最后一个服务器)。

挑选服务器的顺序与其停机时间相乘,并加到“总停机时间成本”中。

设计程序以找到最少的总停机时间成本。

例如,对于数组:

[5, 3, 6, 2, 1, 4]

最短的停机时间是:

5*1 + 4*2 + 3*3 + 6*4 + 2*5 + 1*6 = 62

这是我用来获得此结果的代码:

public static void main(String[] args){
    int[] serverDowntimes = {5, 3, 6, 2, 1, 4};

    int start = 0;
    int end = serverDowntimes.length - 1;
    long totalCost = 0;
    int serverNumber = 1;
    while(start <= end){
        if(serverDowntimes[start] >= serverDowntimes[end]){
            totalCost += serverNumber * serverDowntimes[start];
            start++; //Increment start (i.e. First server in line was recovered)
        }else{
            totalCost += serverNumber * serverDowntimes[end];
            end--; //Decrement end (i.e. Last server in line was recovered)
        }
        serverNumber++;
    }
    System.out.println(totalCost);
}

但是当我有这个数组时,我的代码失败了:

[5, 3, 1, 8, 2, 4]

对于这个数组,我的代码输出:

76 (5*1 + 4*2 + 3*3 + 2*4 + 8*5 + 1*6)

然而,更好的答案应该是:

73 (4*1 + 2*2 + 8*3 + 5*4 + 3*5 + 1*6)

如何修改我的代码,以便它也适用于类似于:

的数组

[5, 3, 1, 8, 2, 4]

1 个答案:

答案 0 :(得分:2)

我编写了蛮力算法,可以测试每种可能的解决方案并选择最佳解决方案。

对于以下问题集:

[5, 3, 1, 8, 2, 4]

它生成以下解决方案:

lowest cost: 72, with combination: [5, 4, 2, 8, 3, 1]

我们可以通过计算证明:

5*1 + 4*2 + 2*3 + 8*4 + 3*5 + 1*6 = 72

这是求解器:

import java.util.*;

class ServersProblemSolver {
    public static void main(String[] args) {
        int[] serverDowntimes = {5, 3, 1, 8, 2, 4};

        int totalCost = Integer.MAX_VALUE;
        List<Integer> bestCombination = new ArrayList<>();

        for (int i = 0; i < Math.pow(2, serverDowntimes.length); i++) {
            int temporaryCost = 0;
            int combination = i;
            int start = 0;
            int end = serverDowntimes.length - 1;
            List<Integer> temporaryCombination = new ArrayList<>();

            for (int k = 0; k < serverDowntimes.length; k++) {
                if (combination % 2 == 1) {
                    temporaryCost += (k + 1) * serverDowntimes[start];
                    temporaryCombination.add(serverDowntimes[start]);
                    start++;
                } else {
                    temporaryCost += (k + 1) * serverDowntimes[end];
                    temporaryCombination.add(serverDowntimes[end]);
                    end--;
                }
                combination /= 2;
            }

            System.out.println("combination " + i + ": " + temporaryCombination + ", cost : " + temporaryCost);

            if (temporaryCost < totalCost) {
                totalCost = temporaryCost;
                bestCombination = temporaryCombination;
            } else {
                temporaryCombination.clear();
            }
        }

        System.out.println("lowest cost: " + totalCost + ", with combination: " + bestCombination);
    }
}

它是如何运作的?

  • 02 ^ N之间采用每个二进制组合,其中N是数组的大小。
  • 根据成功的二进制数字(startend)从01选择服务器
    • 101startendstart
    • 000endendend
    • 110endstartstart
  • 计算当前组合的结果后,检查它是否优于以前的最佳组合,如果是,则保存。