简体   繁体   中英

How can I generate a random combination of array elements so that the sum of their values is between two numbers?

Here's a more detailed explanation on what I've tried to achieve and what I want to achieve.

This is for my JavaScript game project for opening a shipment of goods.

Depending on the shipment quality, you can get:

  • A different random set of items and
  • a random amount of each item but
  • the combined value of all items has to be between two minimum and maximum values AND
  • I want to add some sort of limitation for the amount of each item where I don't want 85 lemons generated because the value of each lemon is 1

I currently have the following:

Let's say that one of my "shipments" is defined as an object.

let shipment = {
 name: 'common',
 items: ['lemons', 'oranges', 'apples', 'plums'],
 minValue: 170,
 maxValue: 230
}
 

Now, out of this object I want to generate the random amount of items so that their sum of values falls between those two min and max values.

The value of each item is stored in my database but for the sake of this example, let's say that their values are defined in a completely different array:

let values = [5, 6, 2, 10]

The order of the elements in the values array corresponds with the value for each item in the items array.

I also want when the algorithm generates an amount for an item in the items array, its pushed into a new result array:

result.push({name: itemName, amount: itemAmount});

So that after the entire generating of those items is done, each item and its corresponding amount generated is an element(object) in the result array that I can use.

I'm using Node.js.

You can generate a random number in that range, then generate 4 weight values to divide that number into 4 unequal parts, here is an example:

 let shipment = { name: 'common', items: ['lemons', 'oranges', 'apples', 'plums'], minValue: 170, maxValue: 230 }; function randomNumberInRange(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } const totalQuantity = randomNumberInRange(shipment.minValue, shipment.maxValue); const weight1 = randomNumberInRange(1, 97); // 97 is used to make sure the remaining 3 weight can be at least 1 const weight2 = randomNumberInRange(1, 98 - weight1); const weight3 = randomNumberInRange(1, 99 - (weight1 + weight2)); const quantities = [weight1, weight2, weight3] .map((v) => (v / 100)) .map((v) => Math.floor(totalQuantity * v)); quantities.push(totalQuantity - quantities.reduce((a, c) => (a + c))); // set the 4th weight to be equal to the remaining quantity shipment.items = shipment.items.map((name, index) => ({ name, quantity: quantities[index] })) console.log(shipment);

The 4 generated values are not that random, the first one will tend to be bigger than the rest, the second one will tend to be smaller than the first but bigger than the third and forth and so on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM