mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-09-20 07:43:04 +08:00
Merge 3c7e32370c
into ca3d16dcce
This commit is contained in:
commit
54afd4cf33
@ -120,30 +120,20 @@ export default class Knapsack {
|
||||
let itemIndex = this.possibleItems.length - 1;
|
||||
let weightIndex = this.weightLimit;
|
||||
|
||||
while (itemIndex > 0) {
|
||||
const currentItem = this.possibleItems[itemIndex];
|
||||
const prevItem = this.possibleItems[itemIndex - 1];
|
||||
|
||||
while (itemIndex >= 0) {
|
||||
// Check if matrix value came from top (from previous item).
|
||||
// In this case this would mean that we need to include previous item
|
||||
// to the list of selected items.
|
||||
if (
|
||||
knapsackMatrix[itemIndex][weightIndex]
|
||||
&& knapsackMatrix[itemIndex][weightIndex] === knapsackMatrix[itemIndex - 1][weightIndex]
|
||||
) {
|
||||
// Check if there are several items with the same weight but with the different values.
|
||||
// We need to add highest item in the matrix that is possible to get the highest value.
|
||||
const prevSumValue = knapsackMatrix[itemIndex - 1][weightIndex];
|
||||
const prevPrevSumValue = knapsackMatrix[itemIndex - 2][weightIndex];
|
||||
if (
|
||||
!prevSumValue
|
||||
|| (prevSumValue && prevPrevSumValue !== prevSumValue)
|
||||
) {
|
||||
this.selectedItems.push(prevItem);
|
||||
// In this case this would mean that we need to include the topmost item with the
|
||||
// same max possible value and the same weight to the list of selected items.
|
||||
while (knapsackMatrix[itemIndex - 1] !== undefined
|
||||
&& knapsackMatrix[itemIndex][weightIndex] === knapsackMatrix[itemIndex - 1][weightIndex]) {
|
||||
itemIndex -= 1;
|
||||
}
|
||||
} else if (knapsackMatrix[itemIndex - 1][weightIndex - currentItem.weight]) {
|
||||
this.selectedItems.push(prevItem);
|
||||
weightIndex -= currentItem.weight;
|
||||
|
||||
// If max possible value in the cell is not zero(and not undefined).
|
||||
if (knapsackMatrix[itemIndex][weightIndex]) {
|
||||
// Add item to knapsack and decrease remaining weight capacity by item's weight.
|
||||
this.selectedItems.push(this.possibleItems[itemIndex]);
|
||||
weightIndex -= this.possibleItems[itemIndex].weight;
|
||||
}
|
||||
|
||||
itemIndex -= 1;
|
||||
|
@ -44,6 +44,26 @@ describe('Knapsack', () => {
|
||||
expect(knapsack.selectedItems[1].toString()).toBe('v4 w3 x 1');
|
||||
});
|
||||
|
||||
it('should solve 0/1 knapsack problem 2', () => {
|
||||
const possibleKnapsackItems = [
|
||||
new KnapsackItem({ value: 5, weight: 3 }),
|
||||
new KnapsackItem({ value: 3, weight: 2 }),
|
||||
new KnapsackItem({ value: 4, weight: 1 }),
|
||||
];
|
||||
|
||||
const maxKnapsackWeight = 5;
|
||||
|
||||
const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight);
|
||||
|
||||
knapsack.solveZeroOneKnapsackProblem();
|
||||
|
||||
expect(knapsack.totalValue).toBe(9);
|
||||
expect(knapsack.totalWeight).toBe(4);
|
||||
expect(knapsack.selectedItems.length).toBe(2);
|
||||
expect(knapsack.selectedItems[0].toString()).toBe('v5 w3 x 1');
|
||||
expect(knapsack.selectedItems[1].toString()).toBe('v4 w1 x 1');
|
||||
});
|
||||
|
||||
it('should solve 0/1 knapsack problem with impossible items set', () => {
|
||||
const possibleKnapsackItems = [
|
||||
new KnapsackItem({ value: 5, weight: 40 }),
|
||||
|
Loading…
Reference in New Issue
Block a user