алгоритм распределения членов группы

Я слушаю какое-то место и получаю некоторые ценности.
Я хочу сгруппировать эти значения для моей идеальной группы.

Например, моя идеальная группа:

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] может дать 2 элемента группе [3], а группа [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] может дать 2 элемента группе [8].

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

Я не знаю, как мне этого добиться. У меня нет опыта распространения.

Любое предложение? Библиотека?

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

Я работал с Boost равномерного распределения. Это не похоже на то, что я сказал, но я думаю, это сработает.

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

Решение

Если я правильно понимаю вопрос, вы рассчитываете, сколько чисел в inputs[] являются ближайшими к разным номерам в group[]и затем сохранить эти подсчеты в позиции, где эти числа в group[] являются. Вы хотели бы иметь возможность распределять количество между различными позициями, но каждая позиция может распределять только две позиции. Это правильно?

Вы должны проверить Повышение / Математика / Distributions.hpp. Он имеет довольно много дистрибутивов, некоторые из которых могут быть полезны в этом случае.

Я думаю, что было бы интересно заметить, что если вы применяете дистрибутив, который вы указали в первоначальном запросе, достаточно много раз, все элементы в group[] будет стремиться к среднему. Другими словами, после применения распределения достаточное количество раз вы всегда получите массив, в котором все элементы равны

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

ИЛИ ЖЕ

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

Например, в массиве, который вы использовали в примере в исходном запросе, все элементы равны 2 или 3. Если вы посмотрите на свои начальные массивы и разделите число на inputs[] по количеству мест в group[], вы получите 2,7. Таким образом, в основном это означает, что, если вы прямо в среднем количество чисел в inputs[] между местами в group[], есть 2,7 номера на место в group[], Если бы вы применили распределение, которое вы подробно описали в исходном запросе, в итоге вы получили бы максимально близкое к среднему значение (у вас, очевидно, не было бы 0,7 числа, поэтому у некоторых позиций есть на одно число больше, чем у других). ,

Я надеюсь, что мое объяснение, по крайней мере, имеет смысл. Мне нужно более четкое определение алгоритма распределения, чтобы попытаться его кодировать. Кажется, что каждый номер в распределенном group[] зависит от трех до пяти чисел (само по себе и от двух до четырех других), поэтому создание цикла, который вычисляет каждую запись, является сложной задачей.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]