mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-11-10 11:09:43 +08:00
Add test for Knapsack 0/1 problem and fix "tracing" part of this algorithm.
This commit is contained in:
parent
94abfec91d
commit
3c7e32370c
@ -120,30 +120,20 @@ export default class Knapsack {
|
|||||||
let itemIndex = this.possibleItems.length - 1;
|
let itemIndex = this.possibleItems.length - 1;
|
||||||
let weightIndex = this.weightLimit;
|
let weightIndex = this.weightLimit;
|
||||||
|
|
||||||
while (itemIndex > 0) {
|
while (itemIndex >= 0) {
|
||||||
const currentItem = this.possibleItems[itemIndex];
|
|
||||||
const prevItem = this.possibleItems[itemIndex - 1];
|
|
||||||
|
|
||||||
// Check if matrix value came from top (from previous item).
|
// Check if matrix value came from top (from previous item).
|
||||||
// In this case this would mean that we need to include previous item
|
// In this case this would mean that we need to include the topmost item with the
|
||||||
// to the list of selected items.
|
// same max possible value and the same weight to the list of selected items.
|
||||||
if (
|
while (knapsackMatrix[itemIndex - 1] !== undefined
|
||||||
knapsackMatrix[itemIndex][weightIndex]
|
&& knapsackMatrix[itemIndex][weightIndex] === knapsackMatrix[itemIndex - 1][weightIndex]) {
|
||||||
&& knapsackMatrix[itemIndex][weightIndex] === knapsackMatrix[itemIndex - 1][weightIndex]
|
itemIndex -= 1;
|
||||||
) {
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
} else if (knapsackMatrix[itemIndex - 1][weightIndex - currentItem.weight]) {
|
|
||||||
this.selectedItems.push(prevItem);
|
// If max possible value in the cell is not zero(and not undefined).
|
||||||
weightIndex -= currentItem.weight;
|
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;
|
itemIndex -= 1;
|
||||||
|
@ -44,6 +44,26 @@ describe('Knapsack', () => {
|
|||||||
expect(knapsack.selectedItems[1].toString()).toBe('v4 w3 x 1');
|
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', () => {
|
it('should solve 0/1 knapsack problem with impossible items set', () => {
|
||||||
const possibleKnapsackItems = [
|
const possibleKnapsackItems = [
|
||||||
new KnapsackItem({ value: 5, weight: 40 }),
|
new KnapsackItem({ value: 5, weight: 40 }),
|
||||||
|
Loading…
Reference in New Issue
Block a user