组成员分配算法

时间:2013-11-15 14:26:23

标签: c++ distribution

我听一些地方并获得一些价值观。 我想将这些值分组为我理想的群体。

例如我理想的小组:

float group[10] = { -27.f, -28.f, -29.f, -30.f, -31.f, -33.f, -36.f, -40.f, -45.f, -50.f };

和一些值:

float inputs[] = {  -54.6501, -56.6878, -49.5917, -42.457, -38.6332,
                    -33.4834, -40.7184, -37.1994, -33.6179, -33.6831, 
                    -31.3403, -31.0914, -28.8593, -25.398, -26.5037, 
                    -50.1182, -50.4615, -47.0196, -35.7407, -34.6086,
                    -31.556, -31.8881, -29.5504, -27.6697, -26.219, 
                    -26.9407, -26.5384
                };

当我分发最近的值时,我发现了计数:

group[0]:6
group[1]:1
group[2]:1
group[3]:0
group[4]:4
group[5]:4
group[6]:2
group[7]:3
group[8]:1
group[9]:5

但实际上我需要分配均衡分布。如果组[0]为6,它可以给组[1]和组[2](它不能给组[3]不同的原因,它可以给出最多2组上或下):

group[0]:3
group[1]:3
group[2]:2
group[3]:0
group[4]:4
group[5]:4
group[6]:2
group[7]:3
group[8]:1
group[9]:5

和组[4]可以给组[3] 2个项目,组[5]可以给组1个项目[6]。

group[0]:3
group[1]:3
group[2]:2
group[3]:2
group[4]:2
group[5]:3
group[6]:3
group[7]:3
group[8]:1
group[9]:5

最后组[9]可以给组[8] 2个项目。

group[0]:3
group[1]:3
group[2]:2
group[3]:2
group[4]:2
group[5]:3
group[6]:3
group[7]:3
group[8]:3
group[9]:3

我不知道如何实现这一目标。我没有分发经验。

有什么建议吗?图书馆?

========================================

我使用了均匀分布。这不像我说的那样,但我觉得它对我有用。

float group[10] = { -27.f, -28.f, -29.f, -30.f, -31.f, -33.f, -36.f, -40.f, -45.f, -50.f };
const int GROUPSIZE = 10;

float groupRatio[10];

std::vector<std::vector<float> > grouped;
grouped.resize(10);

boost::math::uniform_distribution<float> groupDist(-50, -27);

for (int i = 0; i < GROUPSIZE; ++i) {
    std::cout << "cdf[" << i << "]: " << cdf(groupDist, group[i]) << std::endl;
    groupRatio[i] = cdf(groupDist, group[i]);
}

float inputsA[] = {  -54.6501, -56.6878, -49.5917, -42.457, -38.6332,
    -33.4834, -40.7184, -37.1994, -33.6179, -33.6831,
    -31.3403, -31.0914, -28.8593, -25.398, -26.5037,
    -50.1182, -50.4615, -47.0196, -35.7407, -34.6086,
    -31.556, -31.8881, -29.5504, -27.6697, -26.219,
    -26.9407, -26.5384
};
const int INPUTSIZE = 27;

std::vector<float> inputs;
std::copy(&inputsA[0], &inputsA[INPUTSIZE], std::back_inserter(inputs));
std::copy(inputs.begin(), inputs.end(), std::ostream_iterator<float>(std::cout, " "));

std::cout << "\ninputs.size(): " << inputs.size() << std::endl;

float max = -150.f;
for (int i = 0; i < inputs.size(); ++i) {
    if (max < inputs[i])
        max = inputs[i];
}
std::cout << "max : " << max << std::endl;
boost::math::uniform_distribution<float> inputDist(-50, max);

float temp;
for (int i = 0; i < inputs.size(); ++i) {
    temp = boost::math::cdf(inputDist, inputs[i]);
    std::cout << "cdf[" << i << "]: " << temp << std::endl;
    for (int j = 0; j < GROUPSIZE-1; ++j) {
        if (groupRatio[j] >= temp && groupRatio[j+1] < temp)
            grouped[j].push_back(inputs[i]);
        else if (j == GROUPSIZE-2 && groupRatio[j+1] >= temp)
            grouped[GROUPSIZE-1].push_back(inputs[i]);
    }
}

for (int i = 0; i < grouped.size(); ++i)
    std::cout << "grouped[" << i << "]: " << grouped[i].size() << std::endl;

for (int i = 0; i < grouped.size(); ++i)
    for (int j = 0; j < grouped[i].size(); ++j)
        std::cout << "grouped[" << i << "][" << j << "]: " << grouped[i][j] << std::endl;

这是输出:

cdf[0]: 1
cdf[1]: 0.956522
cdf[2]: 0.913043
cdf[3]: 0.869565
cdf[4]: 0.826087
cdf[5]: 0.73913
cdf[6]: 0.608696
cdf[7]: 0.434783
cdf[8]: 0.217391
cdf[9]: 0

-54.6501 -56.6878 -49.5917 -42.457 -38.6332 -33.4834 -40.7184 -37.1994 -33.6179 -33.6831 -31.3403 -31.0914 -28.8593 -25.398 -26.5037 -50.1182 -50.4615 -47.0196 -35.7407 -34.6086 -31.556 -31.8881 -29.5504 -27.6697 -26.219 -26.9407 -26.5384 

inputs.size(): 27

max : -25.398

cdf[0]: 0
cdf[1]: 0
cdf[2]: 0.0165962
cdf[3]: 0.306601
cdf[4]: 0.462027
cdf[5]: 0.671352
cdf[6]: 0.37727
cdf[7]: 0.520307
cdf[8]: 0.665885
cdf[9]: 0.663235
cdf[10]: 0.758463
cdf[11]: 0.76858
cdf[12]: 0.859308
cdf[13]: 1
cdf[14]: 0.955056
cdf[15]: 0
cdf[16]: 0
cdf[17]: 0.121145
cdf[18]: 0.579599
cdf[19]: 0.625616
cdf[20]: 0.749695
cdf[21]: 0.736196
cdf[22]: 0.831217
cdf[23]: 0.907662
cdf[24]: 0.966629
cdf[25]: 0.937294
cdf[26]: 0.953646

grouped[0]: 2
grouped[1]: 3
grouped[2]: 1
grouped[3]: 2
grouped[4]: 3
grouped[5]: 5
grouped[6]: 3
grouped[7]: 2
grouped[8]: 2
grouped[9]: 4

grouped[0][0]: -25.398
grouped[0][1]: -26.219
grouped[1][0]: -26.5037
grouped[1][1]: -26.9407
grouped[1][2]: -26.5384
grouped[2][0]: -27.6697
grouped[3][0]: -28.8593
grouped[3][1]: -29.5504
grouped[4][0]: -31.3403
grouped[4][1]: -31.0914
grouped[4][2]: -31.556
grouped[5][0]: -33.4834
grouped[5][1]: -33.6179
grouped[5][2]: -33.6831
grouped[5][3]: -34.6086
grouped[5][4]: -31.8881
grouped[6][0]: -38.6332
grouped[6][1]: -37.1994
grouped[6][2]: -35.7407
grouped[7][0]: -42.457
grouped[7][1]: -40.7184
grouped[8][0]: -49.5917
grouped[8][1]: -47.0196
grouped[9][0]: -54.6501
grouped[9][1]: -56.6878
grouped[9][2]: -50.1182
grouped[9][3]: -50.4615

1 个答案:

答案 0 :(得分:1)

如果我正确理解了这个问题,你计算inputs[]中最接近group[]中不同数字的数字的数量,然后将这些数字存储到group[]中的这些数字是。您希望能够在不同位置之间分配计数,但每个位置只能分配两个位置。这是对的吗?

你应该看看Boost/Math/Distributions.hpp。它有相当多的发行版,其中一些在这种情况下可能很有用。

我认为可能有趣的是,如果您应用原始请求中概述的分配足够多次,group[]中的所有元素都会趋向于平均值。换句话说,在应用分布足够多次之后,你总是会得到一个数组,其中所有元素都相等

ceil( [total # of numbers in inputs[]] / [# of places in group[]] )

OR

floor( [total # of numbers in inputs[]] / [# of places in group[]] )

例如,在原始请求的示例中,最终得到的数组中,所有元素都是2或3.如果查看起始数组,并将{{1}中的数字除以根据{{​​1}}中的地点数量,你得到2.7。所以基本上,这意味着如果你在inputs[]中的group[]之间的inputs[]平均数字计数,group[]中的每个点数就会有2.7个数字。如果您在原始请求中应用了详细说明的分配,那么最终会得到尽可能接近平均值的分数(显然你不能有0.7的数字,这就是为什么有些职位的数字比其他职位多一个)

我希望我的解释至少有一点意义。我需要更清晰的分配算法定义来尝试编码。看起来分布式group[]中的每个数字都取决于三到五个数字(本身,以及两到四个其他数字),因此创建一个计算每个条目的循环是一个棘手的问题。