У меня есть массив почти отсортированных значений длиной 28 элементов. Мне нужно найти набор значений, который суммируется с целевым значением, предоставленным алгоритму (или, если точная сумма не может быть найдена, ближайшая сумма Ниже целевого значения).
В настоящее время у меня есть простой алгоритм, который выполняет эту работу, но он не всегда находит лучшее соответствие. Он работает в идеальных условиях с определенным набором значений, но мне нужно более надежное и точное решение, которое может обрабатывать более широкий набор наборов данных.
Алгоритм должен быть написан на C, а не на C ++, и предназначен для встроенной системы, так что имейте это в виду.
Вот мой текущий алгоритм для справки. Итерация начинается с самого высокого доступного значения. Если текущее значение меньше целевой суммы, оно добавляет значение к выходным данным и вычитает его из целевой суммы. Это повторяется до тех пор, пока сумма не будет достигнута или пока не закончатся значения. Это сортирует почти восходящий отсортированный список.
//valuesOut will hold a bitmask of the values to be used (LSB representing array index 0, next bit index 1, etc)
void pickValues(long setTo, long* valuesOut)
{
signed char i = 27;//last index in array
long mask = 0x00000001;
(*valuesOut) = 0x00000000;
mask = mask<< i;//shift to ith bit
while(i>=0 && setTo > 0)//while more values needed and available
{
if(VALUES_ARRAY[i] <= setTo)
{
(*valuesOut)|= mask;//set ith bit
setTo = setTo - VALUES_ARRAY[i]._dword; //remove from remaining }
//decrement and iterate
mask = mask >> 1;
i--;
}
}
Еще несколько параметров:
Массив значений: вероятно для сортировки по возрастанию, но не может быть применен, поэтому предположим, что сортировка отсутствует. На самом деле, также могут быть повторяющиеся значения.
Вполне возможно, что массив будет содержать набор значений, которые не могут создать каждую сумму в пределах своего диапазона. Если точная сумма не может быть найдена, алгоритм должен вернуть значения, которые создают следующую наименьшую сумму.