У меня есть код, который генерирует распределение N с плавающей запятой от 0 до 1 на основе параметризованного уравнения. Они нужны мне как 8-битные целочисленные значения, поэтому после этого я масштабирую их до 255 и округляю до ближайшего целого. Мне также нужно, чтобы они были уникальными без повторяющихся значений. Тестировать дубликаты и удалять их довольно тривиально, однако мне нужно сохранить исходный размер числа N точек распространения. В некоторых случаях у меня уже может быть уникальный набор, в этом случае никаких действий не требуется:
0 3 15 40 78 128 177 215 240 252 255
-> Без оп
Но иногда я могу получить что-то вроде:
0 0 0 2 21 128 234 253 255 255 255
В этом случае я хотел бы получить набор, который выглядит следующим образом:
0 1 2 3 21 128 234 252 253 254 255
Я корректирую каждое повторяющееся значение на минимум, необходимый для того, чтобы оно было уникальным, и в то же время поддерживаю монотонный порядок, а также исходное количество точек.
Итак, слева направо мне нужно увеличить первое значение повтора на 1 и так далее. Но обратите внимание, что 4-й элемент равен 2, поэтому мне также необходимо учитывать возможность создания дубликата при увеличении других значений.
Но с правой стороны 255 - это мое максимально возможное значение, поэтому мне нужно, чтобы они опустились на 1, двигаясь влево.
В настоящее время я использую Eigen в качестве контейнера Vector, но я могу использовать все что угодно в STL.
Другие сложности состоят в том, что я не могу заранее знать количество исходных точек, N, которые могут быть любым положительным целым числом от 2 до 255.
Другая, возможно, важная и полезная деталь может заключаться в том, что мой оригинальный набор двойных значений от 0 до 1 гарантированно будет уникальным и монотонно увеличивающимся. Я не знаю, как это можно использовать, но вполне приемлемо пытаться учесть повторы до масштабирования до 255, если есть лучшее решение.
Вот код, который в настоящее время генерирует набор распределения значений типа double, а затем масштабирует его до целых чисел:
Eigen::VectorXi v_i(NUMBER_OF_POINTS); // NUMBER_OF_POINTS: int from 2 to 255
Eigen::VectorXd v_d(NUMBER_OF_POINTS);
double d;
for ( int i = 1; i < v_d.size() - 1; ++i )
{
d = i / ( v_d.size() - 1.0 );
v( i ) = 1.0 / ( 1.0 + pow( d / ( 1.0 - d ), -SLOPE ) ); // SLOPE: double > 0
}
v_d( 0 ) = 0; // Manually setting the endpoints to 0 and 1 to avoid divide by zero error
v_d( v_d.size() - 1 ) = 1.0;
for ( int i = 0; i < v_i.size(); ++i )
{
v_i(i) = round( v_d( i ) * 255 );
}
std::cout << v_i << std::endl;
Заранее спасибо за помощь.