如何将m个数尽量平均分成n组

您所在的位置:网站首页 组合平均分组问题 如何将m个数尽量平均分成n组

如何将m个数尽量平均分成n组

2023-09-08 15:34| 来源: 网络整理| 查看: 265

1 背景

在具体的项目中,经常会碰到稍微复杂一点的算法,很多问题都涉及到资源分配,如何将m个自然数尽可能平均分成n组便是其中一个经常会碰到的问题,很多游戏项目中作资源分配时都可能碰到这样的问题。

2 解决方案

针对这个问题,有两种典型的方法,如下分别进行介绍

2.1 暴力法

最简单直接的方法是暴力法,将m个数分成n组,就是对m进行n划分,找出所有的划分,看哪一种最平均。

显然,这是一种最笨的方法,随着m的增长,这些组合的数量会变得极为庞大,如m=10000, n=100时,光把这些组合计算出来都是一件极其费力的事。这种方法显然行不通。

2.2 动态规划算法

为描述方便,以一个具体例子进行分析,假设m个数为:28, 25, 19, 18, 10, 9, 6, 4, 3, 1,如果分成3组,该如何分?分成4组呢?分成5组呢?

在继续分之前,需要明确什么是“尽可能平均”,假设上例中分成三组数据,每组数据之和为sum1, sum2, sum3,m个数的平均值为:mean,则length = [(sum1-mean)2 + (sum2-mean)2 + (sum3-mean)2]1/2,length值最小的分组,分组最平均。

另外一个问题是:是否能找到最优解或者次有解?这个问题有点棘手,但是如果降低要求,能否找到一个并不离奇的解,则很简单。下面介绍一个能找到次优解的方法,在本文中未证明是否是最优解。

首先计算m个数的n平均值,如上例中所有数的和为123,分成3组的平均值mean为41;

将这m个数按从大到小的顺序进行排序,得到(28, 25, 19, 18, 10, 9, 6, 4, 3, 1);

从最大的数max开始选择,如果max >= mean,则直接将max单独分成一组;否则,将max纳入一组g,并为g继续选择是否有新的数可以加入,这是这一算法中最关键的部分:

(1). 首先计算假设不再有新的数纳入g,则计算delta0 = mean - max和sqrt0 = (mean - max)2; (2). 然后从剩下的数中寻找最接近delta0的数,此时,按照(1)继续计算delta1和sqrt1,再按照(2)继续,直至不能继续; (3). 比较上述过程中可能组合最终的sqrti,选择一个最小的,其核心问题是是否加入一个数到当前组以及加入哪一个数。(这一部分可能描述有些不清楚,请看后面的描述,并在后面的图上动手分组理解)

这个问题说起来有些绕,下面以上面具体的例子进行描述:

1 由计算得10个数的总和为123,分成3组的平均值为41; 2 从大到小开始进行分组,首先将28纳入一个组g,因为28 < 41,所以在剩余的数中继续寻找与delta0 =(41 - 28)=13最接近的数;从大到小遍历的过程中,寻找离13最近的数,得到18和10,显然(18-13)2 > (13-10)2,因此将10纳入g;接着,继续再剩余的数中寻找与(13 - 10)等于3最接近的数,最后得到一个分组(28, 10, 3) 同理,按照此方法,可以得到另外的几个组(25,9,6,1),(19,18,4)

在描述例子的过程当中,最核心的问题是寻找与deltai最接近的数时,到底是加入比deltai大的最近的数p还是加入比deltai小的最近的数q?

如果(deltai - p)2 > (deltai - q)2,则将q加入分组,继续探索deltai+1 = deltai - q; 如果(deltai - p)2


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3