以下是使用动态编程算法解决0-1背包问题的C ++程序。 Keep是一个2D数组,用于确定项目是否包含在最大答案中(使用1和0)。程序编译但运行时出现以下错误: 抛出'std :: length_error'的实例后终止调用 what():basic_string :: _ S_create 中止
这是我的代码:
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;
static ifstream fr;
static vector<int> stolen_Profit;
static vector<int> stolen_Weight;
static vector<string> stolen_Name;
/**class for item object*/
class Item
{
public:
/**constructor that will get information from the file*/
Item()
{
fr>>name>>p>>w;
r=p/w;
}
/**@return the name of the item object*/
string getName()
{return name;}
/**@return the weight of the item object*/
int getWeight()
{return w;}
/**@return the weight of the item object*/
int getProfit()
{return p;}
/**@return the weight of the item object*/
double getRatio()
{return r;}
private:
string name;
double r;
int w, p;
};
int max(int a, int b)
{
int max=a;
if (b>a)
{max=b;}
return max;
}
void finditems(int remainingweight, int item, int **Keep, int Weight[], int Profit[], string Name[])
{
if (item!=0)
{
if(Keep[item][remainingweight]==1)
{
stolen_Weight.push_back(Weight[item]);
stolen_Profit.push_back(Profit[item]);
stolen_Name.push_back(Name[item]);
remainingweight=remainingweight-Weight[item];
item=item-1;
finditems(remainingweight,item, Keep, Weight, Profit, Name);
//add the item to stolen
}
if(Keep[item][remainingweight]==0)
{
item=item-1;
finditems(remainingweight,item, Keep, Weight, Profit, Name);
}
}
else return;
}
void knapsack(int n, int W, int Weight[], int Profit[], string Name[], int *P[], int *Keep[])
{
//set all values in the 0 row to 0
for(int i=0; i<=W; i++)
{
P[0][i]=0;
Keep[0][i]=0;
}
for(int i=0; i<=n; i++)
{
//set all values in the 0 weight column to 0
P[i][0]=0;
Keep[i][0]=0;
for (int j=1; j<=W; j++)
{
if (Weight[i]<=j)
{
P[i][j]= max(P[i-1][j], Profit[i] + P[i-1][j-Weight[i]]);
if (P[i][j]==P[i-1][j])
{Keep[i][j]=0;}
else
Keep[i][j]=1;
}
else
P[i][j]=P[i-1][j];
Keep[i][j]=0;
}
}
finditems(W, n, Keep, Weight, Profit, Name);
int totalweight=0;
/**print out information to output file*/
ofstream fw;
fw.open("outputp1.txt");
//# of items in solution
cout<<stolen_Name.size()<<endl;
//total weight
for(int i=0; i<stolen_Weight.size(); i++)
{
totalweight=totalweight+stolen_Weight[i];
}
cout<<totalweight<<endl;
//total profit
cout<<P[n][W]<<endl;
//print out the information of each item
for(int i=0; i<stolen_Name.size(); i++)
{cout<< stolen_Name[i]<<" "<< stolen_Profit[i] << " "<< stolen_Weight[i]<<endl;}
fw.close();
}
int main()
{
int n, W;
fr.open("inputp1.txt");
fr>>n>>W;
/**create an array of Items objects based on n*/
Item tosteal[n];
int *Profit=new int[n+1];
int *Weight=new int[n+1];
string *Name=new string[n+1];
for (int i=0; i<=n; i++)
{
if (i==0)
{
Profit[i]=0;
Weight[i]=0;
Name[i]="";
}
else
Profit[i]= tosteal[i-1].getProfit();
Weight[i]= tosteal[i-1].getWeight();
Name[i]= tosteal[i-1].getName();
}
int **P= new int *[n+1];
int **Keep= new int *[n+1];
for (int i=0; i<=n; i++ )
{
P[i]=new int [W];
Keep[i]=new int [W];
}
fr.close();
knapsack(n, W, Weight, Profit, Name, P, Keep);
cout <<"Solution to 0-1 Knapsack Problem written to file."<<endl;
//garbage collection
for (int i=0; i<=n;i++)
{
delete P[i];
delete Keep[i];
}
delete P;
delete Keep;
delete Weight;
delete Profit;
delete Name;
//delete stolen_Name;
//delete stolen_Profit;
//delete stolen_Weight;
}
答案 0 :(得分:0)
确保变量n
是您期望的数字(尝试cout << "n = " << n << " W = " << W << '\n';
进行调试)
看起来您可能希望在其自己的块中使用else语句
最好的办法是在调试器中运行代码。你在用Linux吗?如果是,请运行带有gdb [your-command]
的命令,然后键入run
,然后当它崩溃时键入where
以获取堆栈跟踪。它应该告诉你造成崩溃的线路。