I need to manipulate chunks
quantity
until total will be as close as possible to the requirements
. Decimals are ok in the quantity.
Again: I can change only quantity
property.
So if the requirements are {a:500; b:1200; c:1500}, then the quantity
field in the chunks
array should be changed so that when I run this:
// sum all chunks
Object.keys(chunks).forEach(chunk=> {
Object.keys(total).forEach(id=> {
total[id] += chunks[chunk].payload[id] * chunks[chunk].quantity
});
It returns an object as close as possible to {a:500; b:1200; c:1500}
.
How do I do that efficiently?
const chunks = { // <- the chunks
chunk1: {
quantity: 0, // <- the quantity
payload: { a: 19, b: 17, c: 10 }
},
chunk2: {
quantity: 0, // <- the quantity
payload: { a: 17, b: 11, c: 15 }
},
chunk3: {
quantity: 0, // <- the quantity
payload: { a: 7, b: 19, c: 0 }
},
chunk4: {
quantity: 0, // <- the quantity
payload: { a: 14, b: 4, c: 19 }
},
chunk5: {
quantity: 0, // <- the quantity
payload: { a: 3, b: 15, c: 6 }
},
chunk6: {
quantity: 0, // <- the quantity
payload: { a: 10, b: 16, c: 3 }
},
chunk7: {
quantity: 0, // <- the quantity
payload: { a: 2, b: 3, c: 2 }
},
chunk8: {
quantity: 0, // <- the quantity
payload: { a: 14, b: 16, c: 11 }
},
chunk9: {
quantity: 0, // <- the quantity
payload: { a: 7, b: 2, c: 2 }
},
chunk10: {
quantity: 0, // <- the quantity
payload: { a: 1, b: 7, c: 17 }
}
}
const requirements = { // <- the requirements
a: 500,
b: 1200,
c: 1500
}
const total = {
a: 0,
b: 0,
c: 0
}
// sum all chunks
Object.keys(chunks).forEach(chunkId => {
Object.keys(total).forEach(propId => {
total[propId] += chunks[chunkId].payload[propId] * chunks[chunkId].quantity
})
})
console.log(total) // <- i need this to be as close as possible to the `requirements`.
// MY SOLUTION:
const percentages = JSON.parse(JSON.stringify(chunks))
Object.keys(percentages).forEach(chunkId => {
let total = 0
Object.keys(percentages[chunkId].payload).forEach(propId => {
const perc =
percentages[chunkId].payload[propId] / (requirements[propId] / 100)
percentages[chunkId].payload[propId] = perc
total += perc
})
Object.keys(percentages[chunkId].payload).forEach(propId => {
percentages[chunkId].payload[propId] =
percentages[chunkId].payload[propId] / (total / 100)
})
})
const myTotal = {
a: 0,
b: 0,
c: 0
}
Array.from(Array(10)).forEach(() => {
Object.keys(percentages).forEach(chunkId => {
let highestPropId
let highestPropPercentage = 0
Object.keys(percentages[chunkId].payload).forEach(propId => {
const perc = percentages[chunkId].payload[propId]
if (perc > highestPropPercentage) {
highestPropPercentage = perc
highestPropId = propId
}
})
const remainingNum = requirements[highestPropId] - myTotal[highestPropId]
const koe = 0.5
const multiplier =
(remainingNum / chunks[chunkId].payload[highestPropId]) * koe
Object.keys(myTotal).forEach(propId => {
myTotal[propId] += chunks[chunkId].payload[propId] * multiplier
})
chunks[chunkId].quantity += multiplier
})
})
console.log('myTotal', myTotal)
/*
in the console log output you'll see this:
{
"a": 499.98450790851257,
"b": 1202.1742982865637,
"c": 1499.5877967505367
}
compare it with the `requirements` object above:
const requirements = { // <- the requirements
a: 500,
b: 1200,
c: 1500
}
as you see, it's almost the same. I need more efficient solution
*/
It's not accurate and quite inefficient. Any better options?
Notes, answering the first comment:
- Second snippet contains first snippet and my solution.
- The
quantity
is a property inchunks
object. Find it in the very beginning of the first snippet - "As close as possible" means as close to
requirements
as mathematically possible. - Input is in the first code snippet. To get output, pls run the first snippet.
requirements
object. Can't you share a way smaller example with just one requirement? \$\endgroup\$ – GirkovArpa Jul 26 '20 at 0:14quantity
of chunk 4, 6, 7, 8 and 9. It seems rather counterintuitive to me having negative quantities - which would mean, that I have to remove something from a total, that isn't really there to begin with. Or maybe the termquantity
isn't the right/original name for the value? \$\endgroup\$ – user73941 Jul 28 '20 at 5:12