This is my first shot at brute-forcing the NP-complete knapsack problem. In this form you have a list of items which must be thrown off a plane each with a weight and cost. The goal is to throw out some remain_weight while minimizing cost.
Each recursion level(y direction if graphed) is a new remain_weight after items have been selected. A for loop searches through all the items(x direction if graphed)
Test Case 1 - Works
Item / Weight / Cost
0 100 101
1 300 297
What is the best way to put these two functions in a class.
enum item_type {weight, cost};
int algo(int &cost_low, int &cost_high, int throw_weight, int item_id, int item_matrix[][2])
{
int quantity,remainder;
quantity=throw_weight/item_matrix[item_id][weight];
remainder=throw_weight%item_matrix[item_id][weight];
if(remainder==0)
{
cost_low=(quantity-1)*item_matrix[item_id][cost];
cost_high=quantity*item_matrix[item_id][cost];
throw_weight-=(quantity-1)*item_matrix[item_id][weight];
}
else
{
cost_low=(quantity)*item_matrix[item_id][cost];
cost_high=(quantity+1)*item_matrix[item_id][cost];
throw_weight-=(quantity)*item_matrix[item_id][weight];
}
return throw_weight;
}
int branch(int remain_weight)
{
static int depth_level = 0;
static int cost_present=32000;
int remain_weight_next;
int cost_low, cost_high, cost_branch;
depth_level++;
cout << "Entering at depth: " << depth_level << " :remain_weight: " << remain_weight << endl ;
int item_id, item_count=2;
int item_matrix[][2] =
{
{100, 101},
{300, 297},
// {400, 401},
// {800, 800},
// {1200, 1200},
// {1999, 1800},
// {2000, 2000},
};
for(item_id=0; item_id<item_count; ++item_id)
{
cout << "--For loop id is: " << item_id << endl;
if(item_matrix[item_id][weight]<remain_weight)
{
cout << "----item_weight: " << item_matrix[item_id][weight] << " : is less than remain_weight : " << remain_weight << endl;
remain_weight_next=algo(cost_low,cost_high,remain_weight,item_id,item_matrix);
cost_branch = branch(remain_weight_next);
cost_present=cost_low + cost_branch;
if(cost_present>cost_high)
cost_present=cost_high;
cout << "--**remain_weight: " << remain_weight << endl;
cout << "--**cost_low: " << cost_low << endl;
cout << "--**cost_high: " << cost_high << endl;
cout << "--**cost_branch: " << cost_branch << endl;
}
else
{
cout << "----item_weight: " << item_matrix[item_id][weight] << " : is greater than remain_weight : " << remain_weight << endl;
if(cost_present>item_matrix[item_id][cost])
cost_present=item_matrix[item_id][cost];
}
cout << "--**cost_present: " << cost_present << endl;
}
cout << "Leaving at Depth: " << depth_level << endl;
depth_level--;
return cost_present;
}
int &cost_low, int &cost_highis a tip-off. If a function is called repeatedly, and on each iteration modifies the same objects, then that function and those objects should probably be members of the same class.If you look further, you see that
algoalso works oncost_matrix[]andweight_matrix[](No, it’s not a 2D array). These could also become members.branchis a bit complex because you ‘re mixing up things. It’s recursive, but you also initializeitem_matrixin each and every recursion. No problem once you’ve moveditem_matrixinto a class; the ctor will then initialize it. But do allocate that class outsidebranch()for the same recursive reasons.Finally, be a bit more compact. Don’t define objects early; define them when you have a value. Dare to write
cout << "Entering at depth: " << ++depth_level;