简体   繁体   中英

Load Balancing of values into 8 “silos”

I've got a problem I can't seem to crack. It's not that easy to explain so I'll do my best :

I have a really big array of values I have already sorted :

[ 2, 8, 26, ..., 1456, 1879, ..., 7812, 9614, ..., 20 408, 26 584 ]

I have 8 empty "silos" (kind of like an array) with unlimited capacity.

My goal is to fill those silo with all my values in order to make them as balanced as possible. When I say "balanced" , I mean that I want the sum of all the values in a silo to be almost equal to one another.

For example, if my silo 1 has a total sum of 52 000 and my silo 8 has a sum of 30 000 then it's not good. I'd rather have something like 41 000 and 43 500 if possible.

I've already done a round Robin, but it doesn't seem precise enough because I get a quite big difference between my silos. I've looked up bin-packing also but it doesn't seem appropriate to me.

Thank you for any help or advice you may provide!

Optimization problems are never easy, but since you want to minimize the deviation from the average you simply iterate your values from highest to lowest value and add it to the silo with the lowest sum. That way you don't waste too much time on optimization and should (depending on your values) have a relatively good result.

// Generate some random data
int[] values = new int[1000];

Random r = new Random();

for (int i = 0; i < values.Length; i++)
{
    values[i] = r.Next(1, 30000);
}

// Initialize silos
const int siloCount = 8;
List<int>[] result = new List<int>[siloCount];
for (int i = 0; i < siloCount; i++)
{
    result[i] = new List<int>();
}

int[] sums = new int[siloCount];
int[] indices = Enumerable.Range(0, siloCount).ToArray();

// Iterate all values in descending order
foreach (int value in values.OrderByDescending(i => i).ToList())
{
    // Find silo with lowest sum (or one of them)
    int siloIndex = indices.First(i => sums[i] == sums.Min());

    // Add to collection and sum - so we don't have to call .Sum() every iteration
    sums[siloIndex] += value;
    result[siloIndex].Add(value);
}

Debug.WriteLine(String.Join("\r\n", result.Select(s => s.Sum())));

.Net Fiddle

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