LINUX.ORG.RU

Комбинаторная переборка задачи - как лучше реализовать?


0

0

Нужно перебрать все возможные решения многомерной задачи, сохраняя лучшие N вариантов решения. Лучшие - согласно определенной функции оценки. Предпологается, что если растояние между двумя телами в данном многомерном пространсве достаточно близко, то только одно из них будет сохранено. Моя стратегия:
<PSEUDOCODE>
variant=problem.nextSolution();
while (variant.isValid()){
bool insert=true;
for (list<Variant>::iterator i=bestList.begin();i!=bestList.end();++list){
if (distance(variant, *i) < threshold){
insert=false;
break;
}
if (insert){
variant.calculateScoringFunction();//(много времени)
//пройтись по листу
//и вставить вариант в нужном месте
//если вставлено как минимум N
//вариантов, убрать последний
}
variant=problem.nextSolution();
}
</PSEUDOCODE>

Есть ли стратегии лучше?
Стоит ли, для хранения лучших результатов, использовать std::map (или какой-то другой sorted conainer) вместо std::list?

Пару пояснений и оговорок:
0. язык - С++
1. вычесление "функции оценки" забирает раза в 4-5 больше времени, чем вычесление растояния между телами в пространсве поэтому вычеслять её до того, как уверены, что вариант интересен - не имеет смысла.
2. очень и очень не хочется иметь дело с динамичеким выделением (и освобождением) памяти
3. Может вопрос и OT, так как к линуксу прямого отнашения не имеет (разве, что пишется на оном), но опыт показывает, что на этом форуме довольно высокое отношение сигнала к шуму ("signal to noise ratio") благодоря тому, что его посещают специалисты во многих облостях.

★★

Имхо, единственное "фундаментальное", что тебе можно посоветовать при такой постановке задачи - постараться заменить оценочную функцию, таким образом, чтобы оценивать расстояние не между всеми "лучшими" и одним "кандидатом", а между некоторым "усредненным лучшим" (или самым худшим из лучших (если можешь такого определить)) и кандидатом. Так вроде проще должно быть.

Использовать map имхо нерационально, ибо map лучше (ну не всегда конечно) всего подходит для создания ассоциативных структур данных, а тут ассоциативностью даже и не пахнить =)

Если не хочешь иметь дело с выделением памяти юзай статический массив при условии что N известно или выделяй память заранее. Для списков идельный вариант выделять память заранее - создавать два списка: один из заполненных ячеек, а другой из пустых. Изначально список из заполненных ячеек пуст, а список из пустых ячеек полон (там N элементов). При занесении очередного лучшего решения берется ячейка из пустого списка и прекрепляется к ячейкам из заполненного. При выкидовании худшего решения "заполненная" ячейка уходит в пустые. Ну и т.д. Впрочем судя по твоему коду тебе оно и не надо.

BottleHunter
()
Ответ на: комментарий от BottleHunter

>ли выделяй память заранее. Для списков идельный вариант выделять память >заранее - создавать два списка: один из заполненных ячеек, а другой из пустых.

и это оптимизация? из какого вы века?
так давно поступает malloc и т.д., т.е. выделяет больше памяти чем ты просишь,
а потом отдает ее программе кусочками больше не обращаясь к ОС.

anonymous
()
Ответ на: комментарий от anonymous

malloc использует слишком общую стратегию, которая может быть не так эффективна, как предложенная стратегия для частного случая. Так что не надо на меня морковь грызть.

BottleHunter
()

> Стоит ли, для хранения лучших результатов, использовать std::map (или какой-то другой sorted conainer) вместо std::list?

std::heap, std::priority_queue

dilmah ★★★★★
()

Есл&#1110; память позволяет &#1110; простраство евкл&#1110;дово (ну &#1110;л&#1110; для него определена какая н&#1110;ть метр&#1110;ка) можно подумать про сетку для оценк&#1110; расстоян&#1110;я, это сразу уменьш&#1110;т ч&#1110;сло операц&#1110;й.

Аналог&#1110;чно, есл&#1110; можно выбрать алгор&#1110;тм обхода тел так&#1110;м, что бы расстоян&#1110;е между телам&#1110; варажалось в шагах алгор&#1110;тма - это поможет уменьш&#1110;ть ч&#1110;сло операц&#1110;й.

Есл&#1110; функц&#1110;я оценк&#1110; гладкая, можно подумать про метод град&#1110;ентного спуска.

Есл&#1110; функц&#1110;я оценк&#1110; &#1110; метр&#1110;ка позволяют, можно подумать про аналог PIC решен&#1110;я с&#1110;стемы заряженных тел (ввод&#1110;ться сетка, &#1110; вместо решен&#1110;я каждый-с-каждым решается каждый-с-сеткой, факт. &#1110;нтегральные уравнен&#1110;е заменяются д&#1110;ф-м&#1110; для потенц&#1110;ала). Но это для кулона вооб&#1118;е-то...

AIv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.