我正在尝试通过组合来解决问题:
我收到了一系列包含可用性百分比的产品,必须计算出最有效,最便宜的组合总和以获得给定的可用性百分比。有一些规则使其变得更困难。
鉴于以下问题:
[{
"name": "network 1",
"availability": 0.5,
"cost": 20,
},
{
"name": "network 2",
"availability": 0.75,
"cost": 30,
}]
我需要使用以下公式找到最有效和最便宜的组合,以计算可用性:
1 - (1 - availability A) * (1 - availability B)… * (1 - availability n)
要求/规则:
cost
方面最便宜的组合最后,它应该打印用于解决方案的项目以及总成本。
我尝试使用有界/无界背包问题以及最小成本路径和子集总和来解决它,但找不到解决方案。同样在最后,它仅打印假定的解决方案,但我不知道如何获取用于获得该解决方案的物品。
最后,我回到了无限制的背包,因为它有很多重复,到目前为止,我已经做到了:
private static int max(int i, int j) {
return (i > j) ? i : j;
}
private static int unboundedKnapsack(int W, int n, List<Long> val, List<Long> wt) {
int dp[] = new int[W + 1];
for(int i = 0; i <= W; i++){
for(int j = 0; j < n; j++){
if(wt.get(j) <= i){
dp[i] = max(dp[i], Math.toIntExact(dp[(int) (i - wt.get(j))] + val.get(j))); // TODO: can't figure out how to implement 1 - (1 - availability A) * (1 - availability B)… * (1 - availability n) instead.
}
}
}
return dp[W];
}
public static void main(String[] args) {
String problem = "" +
"[{\"function\":\"Server\", " +
"\"name\":\"server 1\", " +
"\"availability\":5, " +
"\"cost\":10 }, " +
"{\"function\":\"Server\", " +
"\"name\":\"server 2\", " +
"\"availability\":10, " +
"\"cost\":30 }, " +
"{\"function\":\"Server\", " +
"\"name\":\"server 3\", " +
"\"availability\":15, " +
"\"cost\":20 }] ";
JSONParser parser = new JSONParser();
try{
Object obj = parser.parse(problem);
JSONArray array = (JSONArray) obj;
List<Long> valArray = new ArrayList<>();
List<Long> wtArray = new ArrayList<>();
for (Object value : array) {
JSONObject o = (JSONObject) value;
Long cost = (Long) o.get("cost");
valArray.add(cost);
Long availability = (Long) o.get("availability");
wtArray.add(availability);
}
int W = 100; // TODO: should be the required availability i.e 0.9999. Can't figure out how to get it to work with double values
int n = valArray.size();
System.out.println("cost: " + unboundedKnapsack(W, n, valArray, wtArray));
} catch(ParseException pe) {
System.out.println("position: " + pe.getPosition());
System.out.println(pe);
}
}
目前,我仅将成本作为输出。因此,如果您运行代码ubove,则应该得到:
cost: 300
但是我想要实现的输出是这样的:
availability: 0.9999
items: server 1, server 2...
cost: 300
如果任何人都有解决此问题的算法的想法,我将不胜感激。
答案 0 :(得分:0)
可以使用类似于Is there any algorithm to address the longest common subsequent problem with different weights for each character?的想法通过动态编程来解决。
这个想法是您通过增加成本和增加可用性来建立一个表条目。每个条目包含以下数据:
total_cost: ...
total_availability: ...
last_item: ...
previous_entry:
请注意,previous_entry
的数据类型是递归的,因此,从任何条目开始,您都可以按照链条进行操作,以获取包含的所有项目。
您的表开始时只有一个条目:
{total_cost: 0, total_availability: 0.0, last_item: null, previous_entry: null}
对于具有非零可用性的每个项目,请获取表中的每个现有元素,然后递归建立一系列具有可用性直至目标的条目。然后,您可以按成本升序然后按可用性降序对所有条目(包括之前的条目和创建的条目)进行排序。然后,仅使用那些元素重新构建表,以使没有等价或更低成本的元素具有更高的可用性,而所有可用性超过目标的元素都被视为处于目标可用性。
浏览完所有项目之后,表中至少包含目标可用性的条目将是您的答案,并且您可以递归地遍历previous_entry
以找出需要哪些项目以及需要多少项目找到它。
这将花费时间,该时间是条目数量以及需要多少可能成本的多项式。