Is there an algorithm that can solve this variation of the Knapsack Problem? - knapsack-problem

I want to do a variation on the 0-1 knapsack problem. Just like the original problem each item would have a weight and value, and you are minimizing weight and maximizing value. However each item would be part of a set e.g. Book1(value, weight, set).
I need an algorithm that can sort these, given an upper limit on each individual set. So for instance Set A would be (Book1, Book2, Book3) and I could only have
3 items from set A in the entire knapsack.
There would be no limits on individual items, so I could take as many Book1's as I wished, but I couldn't take more than Set A would allow me to take. The entire knapsack would have multiple sets each with multiple items.
I've tried individually solving each set before solving the problem as a whole using the solutions from each set, but it gives me obviously suboptimal solutions.
How should I design my code so that it produces the best result?

Related

Which mathematical optimization problem is this?

I have an combinational optimization problem and I do not know its name in literature.
My problem is the following:
I have n sets containing exclusive elements, so each element is present only in a set.
An element is characterized by 2 constraints values, and one profit.
I have to choose an element from each set in order to maximize the sum of the profits, while keeping the sum of each constraint below a a specified limit.
Is this an already studied problem? WHich is its name?
Can I assimilate it to an already studied problem?
Thanks to #Berthur & #mrBen replies, I discovered that this is a multiple-constrained knapsack problem where you have to create an indicator variable to force that only one element will be chosen by each set
The problem you're describing is know as the multiple-choice knapsack problem. In your case, as you have 2 constraints, it's actually a 2-dimentional multiple-choice knapsack problem.
With the keywords multi-dimentional multiple-choice knapsack problem (sometime abbreviated as MMKP) you should be able to find the corresponding literature.

Return N Optimal Choices for Multiple Choice Knapsack Variation

Problem
I'm trying to return N optimal answers (for an exact number I want 250). From what I understand with dynamic programming is that it will return one most optimal answer. So I believe I have to use backtracking in order to generate N optimal answers.
For the knapsack variant problem, I have a maximum weight that the combination of objects should not pass. I have 4 sets of objects, and exactly one must be chosen from each set to give the highest value without surpassing the weight constraint. Each object in the sets have a value and a weight.
The sets have 164, 201, 90 and 104 objects which means there are 308,543,040 variations to try. I have a brute force algorithm implemented but it takes forever.
Attempts At Optimization
So far, my attempt at optimizing is to preprocess the input sets by sorting by increasing weight. (lowest first). At the addition of each object, if the constraint weight is greater than the object's combination weight, then I can skip the rest of the set since all other options will not be valid. This can be run at any level of the recursive function.
I also have a minimum heap that stores the maximum values I've found. If the combination of four objects is less than the top of the heap, then it will not be added. Otherwise, pushpop to the heap. I'm not sure if I can use this to optimize the backtracking even further, since it requires all four objects to be selected. It's used more as validation rather than improving the speed.
Questions
Are there any other optimizations I can do with backtracking that will speed up the process of finding N optimal answers? Have I exhausted optimization and should just use multiple threads?
Is it possible to use dynamic programming with this? How can I modify dynamic programming to return N optimal choices?
Any other algorithms to look into?
Since exactly one item has to be picked from each set, you can try this optimization:
Let the sets be A,B,C,D.
Create all combinations of items from sets A,B together and sets C,D together. This will have O(n^2) complexity, assuming lists have length n. Let the combination lists be X and Y now.
Sort X and Y based on weight. You can use something like a cumulative array to track the combination with the max possible value under a given weight. (Other data structures might be used for the same task as well, this is just a suggestion to highlight the underlying idea).
Create a max heap to store the combinations with max values
For each combination in X, pick the combination in Y with the highest value under the constraint that it's weight is <= target weight - X_combination_weight. Based on this combination's value, insert it in the max heap.

Multiple Set Knapsack Variation

I have been trying to find a variation on the knapsack problem that fits my problem, but either I don't understand the definitions on wikipedia well enough (likely) or I am looking in the wrong places.
My problem requires the maximization of value across multiple sets of data. Given 3 sets of data, I want to be able to pick exactly 2 members from each set while maximizing the profit.
Does anyone know of a variation of the knapsack problem that I can look into to do this?
Thank you

Multiple Knapsack, weight = profit

I have a research on Knapsack Problems. Now I stopped on special type of a Multiple Knapsack Problem, where weight of each item is equal with profit of this item.
I can't find any paper saying anything about the complexity of this problem. Is it NP-complete or not?
Any help will be appreciated.
I found a problem that can be reduced to mine - The Multiple Subset Sum Problem. The Multiple Subset Sum Problem (MSSP) is the selection of items from a given ground set and their packing into a given number of identical bins such that the sum of the item weights in every bin does not exceed the bin capacity and the total sum of the weights of the items packed is as large as possible. It can be easily reduced to my problem. It proves that my problem is NP-hard.
This problem is NP-hard via a reduction from the set partition problem. In that problem, you're given a set of integers and are asked whether it's possible to split that set into two sets with the same sum. You can reduce it to your problem as follows: if the set has sum 2k, create two knapsacks of capacity k each and create one item for each number in the set to split. Then, any way of perfectly filling the knapsacks corresponds to a partition of the original set and vice-versa. (If the sum of the numbers isn't even, just map the problem instance to an unsolvable instance of your knapsack problem).
Hope this helps!

How can I efficiently find the subset of activities that stay within a budget and maximizes utility?

I am trying to develop an algorithm to select a subset of activities from a larger list. If selected, each activity uses some amount of a fixed resource (i.e. the sum over the selected activities must stay under a total budget). There could be multiple feasible subsets, and the means of choosing from them will be based on calculating the opportunity cost of the activities not selected.
EDIT: There are two reasons this is not the 0-1 knapsack problem:
Knapsack requires integer values for the weights (i.e. resources consumed) whereas my resource consumption (i.e. mass in the knapsack parlance) is a continuous variable. (Obviously it's possible to pick some level of precision and quantize the required resources, but my bin size would have to be very small and Knapsack is O(2^n) in W.
I cannot calculate the opportunity cost a priori; that is, I can't evaluate the fitness of each one independently, although I can evaluate the utility of a given set of selected activities or the marginal utility from adding an additional task to an existing list.
The research I've done suggests a naive approach:
Define the powerset
For each element of the powerset, calculate it's utility based on the items not in the set
Select the element with the highest utility
However, I know there are ways to speed up execution time and required memory. For example:
fully enumerating a powerset is O(2^n), but I don't need to fully enumerate the list because once I've found a set of tasks that exceeds the budget I know that any set that adds more tasks is infeasible and can be rejected. That is if {1,2,3,4} is infeasible, so is {1,2,3,4} U {n}, where n is any one of the tasks remaining in the larger list.
Since I'm just summing duty the order of tasks doesn't matter (i.e. if {1,2,3} is feasible, so are {2,1,3}, {3,2,1}, etc.).
All I need in the end is the selected set, so I probably only need the best utility value found so far for comparison purposes.
I don't need to keep the list enumerations, as long as I can be sure I've looked at all the feasible ones. (Although I think keeping the duty sum for previously computed feasible sub-sets might speed run-time.)
I've convinced myself a good recursion algorithm will work, but I can't figure out how to define it, even in pseudo-code (which probably makes the most sense because it's going to be implemented in a couple of languages--probably Matlab for prototyping and then a compiled language later).
The knapsack problem is NP-complete, meaning that there's no efficient way of solving the problem. However there's a pseudo-polynomial time solution using dynamic programming. See the Wikipedia section on it for more details.
However if the maximum utility is large, you should stick with an approximation algorithm. One such approximation scheme is to greedily select items that have the greatest utility/cost. If the budget is large and the cost of each item is small, then this can work out very well.
EDIT: Since you're defining the utility in terms of items not in the set, you can simply redefine your costs. Negate the cost and then shift everything so that all your values are positive.
As others have mentioned, you are trying to solve some instance of the Knapsack problem. While theoretically, you are doomed, in practice you may still do a lot to increase the performance of your algorithm. Here are some (wildly assorted) ideas:
Be aware of Backtracking. This corresponds to your observation that once you crossed out {1, 2, 3, 4} as a solution, {1, 2, 3, 4} u {n} is not worth looking at.
Apply Dynamic Programming techniques.
Be clear about your actual requirements:
Maybe you don't need the best set? Will a good one do? I am not aware if there is an algorithm which provides a good solution in polynomial time, but there might well be.
Maybe you don't need the best set all the time? Using randomized algorithms you can solve some NP-Problems in polynomial time with the risk of failure in 1% (or whatever you deem "safe enough") of all executions.
(Remember: It's one thing to know that the halting problem is not solvable, but another to build a program that determines whether "hello world" implementations will run indefinetly.)
I think the following iterative algorithm will traverse the entire solution set and store the list of tasks, the total cost of performing them, and the opportunity cost of the tasks not performed.
It seems like it will execute in pseudo-polynomial time: polynomial in the number of activities and exponential in the number of activities that can fit within the budget.
ixCurrentSolution = 1
initialize empty set solution {
oc(ixCurrentSolution) = opportunity cost of doing nothing
tasklist(ixCurrentSolution) = empty set
costTotal(ixCurrentSolution) = 0
}
for ixTask = 1:cActivities
for ixSolution = 1:ixCurrentSolution
costCurrentSolution = costTotal(ixCurrentSolution) + cost(ixTask)
if costCurrentSolution < costMax
ixCurrentSolution++
costTotal(ixCurrentSolution) = costCurrentSolution
tasklist(ixCurrentSolution) = tasklist(ixSolution) U ixTask
oc(ixCurrentSolution) = OC of tasks not in tasklist(ixCurrentSolution)
endif
endfor
endfor

Resources