Algorithm 具有连续(非独立)约束的背包
我看着。然而,我正在解决一个稍微不同的问题,其中约束是预算,价格,是双精度的,而不是整数。所以我想知道如何修改它?Double是“连续的”,不像整数,我可以有1,2,3。。。。我想我不会做0.0,0.1,0.2 更新1 我想把double乘以100转换成int。货币只有小数点后两位。但这意味着价值范围将非常大 更新2 我需要解决的问题是: 项目具有价格(双倍)和满意度(整数)值。我有一个预算作为约束,我需要最大限度地满足价值 在youtube视频中,作者创建了两个2d数组,如int[numItems][possibleCapacity(weight)]。在这里,我不能,因为预算是双精度的而不是整数 让你的眼睛看看。 对不起,我没有评论权限 编辑1 你是说约束是预算而不是背包重量? 这仍然是一个背包问题 或者你是说你有分数而不是项目值作为整数(0-1背包问题)。那么贪婪的方法就行了 编辑2 如果我正确理解你的问题。。它说 我们有Algorithm 具有连续(非独立)约束的背包,algorithm,dynamic-programming,knapsack-problem,Algorithm,Dynamic Programming,Knapsack Problem,我看着。然而,我正在解决一个稍微不同的问题,其中约束是预算,价格,是双精度的,而不是整数。所以我想知道如何修改它?Double是“连续的”,不像整数,我可以有1,2,3。。。。我想我不会做0.0,0.1,0.2 更新1 我想把double乘以100转换成int。货币只有小数点后两位。但这意味着价值范围将非常大 更新2 我需要解决的问题是: 项目具有价格(双倍)和满意度(整数)值。我有一个预算作为约束,我需要最大限度地满足价值 在youtube视频中,作者创建了两个2d数组,如int[numIte
n
种商品,从1到n。每种商品i
都有一个值vi
和一个价格pi
。我们通常假设所有的值和价格都是非负的。预算是B
该问题最常见的表述是0-1背包问题
,该问题将每种物品的xi
份数限制为零或一份。从数学上讲,0-1背包问题可以表示为:
n
maximize E(vi.xi)
i=i
n
subject to E(pi.xi) <= B, xi is a subset of {0,1}
i=1
您甚至可以将实数转换为int,正如您所提到的
是的,值的范围非常大,你还必须理解背包是NP完全的,也就是说,没有有效的算法来解决这个问题。仅使用DP的
伪多项式
解决方案。请参阅和。如果您想使用具有任意精度的浮点数(即,没有固定数量的小数),并且它们不是分数,则动态编程将不起作用
动态规划的基础是存储特定输入的先前计算结果。因此,如果使用具有任意精度的浮点数,那么对于每个可能的浮点数,实际上都需要无限的内存,当然,还要进行无限计算,这是不可能的,也是非最优的
但是,如果这些数字具有固定的精度(与货币一样,货币只有两个十进制数字),您可以通过将它们相乘(如您所述)将其转换为整数,然后像往常一样解决背包问题。这不是您问题的答案,但也可能是您正在寻找的: 线性规划 我曾经编写过一个简单的代码来解决您描述的问题。它不使用背包算法,而是使用单纯形法
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用Microsoft.SolverFoundation.Common;
使用Microsoft.SolverFoundation.Services;
名称空间优化程序
{
类项目
{
公共字符串ItemName{get;set;}
公共双价{get;set;}
公共双满意{get;set;}
静态void Main(字符串[]参数)
{
//我们的数据、预算和项目,以及各自的满意度和价格值
双倍预算=100.00;
列表项=新列表()
{
新项目(){
ItemName=“产品1”,
价格=20.1,
满意度=2.01
},
新项目(){
ItemName=“产品2”,
价格=1.4,
满意度=0.14
},
新项目(){
ItemName=“产品3”,
价格=22.1,
满意度=2.21
}
};
//用于解决问题的变量。
SolverContext上下文=SolverContext.GetContext();
Model Model=context.CreateModel();
长期目标=0;
术语约束=0;
foreach(项目中的项目i)
{
决策决策=新决策(Domain.integernonegative,i.ItemName);
model.AddDecision(decision);//每个项都是一个决策-算法是否应该增加此项?
目标+=i.满意度*决策;//决策将包含数量。
约束+=i.价格*决策;
}
constraint=constraint您必须执行更新1中所说的内容:以美分表示预算和项目价格(假设我们谈论的是美元)。然后我们谈论的不是任意精度或连续数字。每个价格(和预算)将是一个整数,只是那个整数将代表美分
为了让事情变得更简单,我们假设预算为10美元。问题是背包容量必须包含以下所有值:
[0.00, 0.01, 0.02, 0.03, ..., 9.99, 10.00]
这些值是两个多值。解决方案矩阵和保留矩阵的每一行都有1001列,因此您将无法手动解决问题(如果预算为数百万美元,即使是一台计算机也可能有困难),但这是原始问题固有的(您对此无能为力)
您的最佳选择是使用一些关于背包的现有代码,或者编写自己的代码(我不建议这样做)
如果您找不到关于背包的现有代码,并且熟悉Linux/Mac,我建议您安装(GLPK)并解决这个问题
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Services;
namespace LPOptimizer
{
class Item
{
public String ItemName { get; set; }
public double Price { get; set; }
public double Satisfaction { get; set; }
static void Main(string[] args)
{
//Our data, budget and items with respective satisfaction and price values
double budget = 100.00;
List<Item> items = new List<Item>()
{
new Item(){
ItemName="Product_1",
Price=20.1,
Satisfaction=2.01
},
new Item(){
ItemName="Product_2",
Price=1.4,
Satisfaction=0.14
},
new Item(){
ItemName="Product_3",
Price=22.1,
Satisfaction=2.21
}
};
//variables for solving the problem.
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Term goal = 0;
Term constraint = 0;
foreach (Item i in items)
{
Decision decision = new Decision(Domain.IntegerNonnegative, i.ItemName);
model.AddDecision(decision); //each item is a decision - should the algorithm increase this item or not?
goal += i.Satisfaction * decision; //decision will contain quantity.
constraint += i.Price * decision;
}
constraint = constraint <= budget; //this now says: "item_1_price * item_1_quantity + ... + item_n_price * item_n_quantity <= budget";
model.AddConstraints("Budget", constraint);
model.AddGoals("Satisfaction", GoalKind.Maximize, goal); //goal says: "Maximize: item_1_satisfaction * item_1_quantity + ... + item_n_satisfaction * item_n_quantity"
Solution solution = context.Solve(new SimplexDirective());
Report report = solution.GetReport();
Console.Write("{0}", report);
Console.ReadLine();
}
}
}
[0.00, 0.01, 0.02, 0.03, ..., 9.99, 10.00]
Define K[0..M, 0..n] where K[j, i] = optimal value of items in knapsack of size j, using only items 1, ..., i
for j = 0 to M do K[j,0] = 0
for i = 1 to n do
for j = 0 to M do
//Default case: Do not take item i
K[j,1] = K[j, i-1]
if j >= w_i and v_i+K[j-w, i-1] > K[j, i] then
//Take item i
K[j,i] = v_i + K[j-w_i, i-1]
Define L[0..S, 0..N] where L[j, i] = minimal weight of items in knapsack of total value >= j, using only items 1, ..., i
and S = total value of all items
for j = 0 to S do L[j, 0] = 0
for i = 0 to n do
for j = 0 to S do
//Default case: Do not take item i
L[j,i] = L[j, i-1]
if j >= v_i and L[j-v_i, i-1] + w_i < L[j, i] then
//Take item i
L[j, i] = L[j -v_i, i-1] + w_i