分数背包边缘箱
Fractional Knapsack fringe cases
我一直在尝试解决分数背包问题,作为贪婪算法教程的一部分。下面的代码片段是我的代码,它似乎适用于基本情况,因为我尝试运行一些基本测试,例如必须选择两个完整的项目,然后选择第三个项目的一小部分。但是,当我将其输入测试套件时,此算法总是无法通过测试。
失败案例 #6/13:错误答案 得到: 5810.101954463027 预期: 7777.731
我一直盯着代码,试图找出它失败的边界情况在哪里,而且我在这方面失败得很厉害,所以我认为一些新鲜的眼光会有所帮助。作为参考,我添加了一个算法,该算法实际上传递了我下面的边缘情况。
我的算法(不起作用(
double get_optimal_value(int capacity, vector<int> weights, vector<int> values) {
double value = 0;
vector<double> valuePerWeight;
// Populating an array called valuePerWeight with ratios of value:weight
for (int i=0; i < weights.size(); i++) {
double valueWeightRatio = values[i]/weights[i];
valuePerWeight.push_back(valueWeightRatio);
}
// While there are still items to choose, and the bag is not full
while (weights.size() > 0 && capacity > 0) {
double max;
int itemNum;
// Going through every item, find the item with the highest valuePerWeight and record it
for (int i=0; i < weights.size(); i++) {
if (valuePerWeight[i] > max) { // If an item has been found to have a valuePerWeight greater than the previous max, update the new max and item number
max = valuePerWeight[i];
itemNum = i;
}
}
// If there is enough space in the knapsack to put the item with the highest valuePerWeight
if (capacity >= weights[itemNum]) {
capacity = capacity - weights[itemNum]; // Adding it to the bag, and updating the capacity and value
value = value + values[itemNum];
// Removing the item from the arrays to ensure that it doesn't get picked again
weights.erase(weights.begin() + itemNum);
values.erase(values.begin() + itemNum);
valuePerWeight.erase(valuePerWeight.begin() + itemNum);
max = 0;
itemNum = 0;
}
// If there isn't enough space in the knapsack to put the whole item with highest valuePerWeight in
else if (capacity < weights[itemNum]) {
// Calculate what fraction of the item can be put in
double fraction = (double)capacity / (double)weights[itemNum];
// Put in that fraction of the item and update the capacity and value
value = value + (double)fraction*values[itemNum];
capacity = capacity - (double)fraction*weights[itemNum];
return value;
}
}
return value;
}
有效的算法
int get_max_index (vector<int> weights, vector<int> values) {
int max_i = 0; // index of the item with the highest value:weight ratio
double max = 0; // the max value:weight ratio we've seen so far
for (int i = 0; i < weights.size(); i++) { // iterating through the weights
if (weights[i] != 0 && (double)values[i]/weights[i] > max) { // if the weights are not 0 and the value:weight ratio we've seen is the highest so far
max = (double)values[i]/weights[i]; // update the max value
max_i = i; // capture the index of the item with the highest value:weight ratio
}
}
return max_i;
}
double get_optimal_value(int capacity, vector<int> weights, vector<int> values) {
double value = 0.0; // The answer to be returned, which is the value of the bag after putting all the items
for (int i = 0; i < weights.size(); i++) { // Running this loop for every item in the bag
if (capacity == 0) return value; // If the capacity of the bag has reached 0, return value
int index = get_max_index(weights, values); // Get the index of the current item with the highest value:weight ratio
int a = std::min(capacity, weights[index]); // Return the lower of the two: Remaining capacity of the bag or the weight of the item with the highest value:weight ratio
value += a * (double)values[index]/weights[index]; // If there is sufficient capacity, put the whole item in, else, place a fraction of the item in: (capacity/weight)*value
weights[index] -= a; // Update the item by removing it
capacity -= a; // Update the capacity
}
return value;
}
我发现了问题!
我没有将值转换为双精度值,因此在值:权重比相差很小的情况下,我弄错了。
此更改修复了算法。
// Populating an array called valuePerWeight with ratios of value:weight
for (int i=0; i < weights.size(); i++) {
double valueWeightRatio = (double)values[i]/weights[i];
valuePerWeight.push_back(valueWeightRatio);
}
相关文章:
- 0-1背包代码中的错误.我的代码中有什么错误
- 如何获取边缘窗口句柄 (HWND)?
- 提升如何在图形可视化中写入边缘的权重?
- 在 c++ 中使用 Tensorflow Lite 在边缘 TPU 上运行"mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite"时出现问题
- 分数背包边缘箱
- 具有多种约束(例如重量、体积等)的背包
- 应用程序无法找到铬边缘浏览器
- 背包问题,视觉工作室问题
- 分段故障背包问题
- 0-1 大重量背包
- SFML C++ Canny边缘检测双刃
- 难以使球从屏幕边缘反弹
- 我的精灵使用名为 ASGE 的C++框架卡在屏幕边缘
- 无法在 vtk 中重新着色边缘
- 如何使用提升make_label_writer写入边缘属性?
- 使用 epoll 边缘触发器的套接字上的数据过多
- 迭代提升反向图中的边缘
- 如何在提升图中访问边缘信息?
- Microsoft具有本机消息传递和非持久连接的边缘扩展不起作用
- 有没有一种方法可以使用弗洛伊德-沃歇尔算法给出最短路径,其中存在负权重循环而不允许重叠边缘?