Вы можете сгенерировать все подмножества с использованием метода Branch-and-bound: вы можете генерировать все подмножества поэтапно (генерируя надмножество уже определенных подмножеств), используя в качестве условия чернослива «не исследует эту ветвь дерево, если корень не удовлетворяет ограничению ".
Если вы хотите быть общим в отношении ограничения, я думаю, что это лучшая стратегия.
Обязательно введите код, который генерирует подмножества, в противном случае вы создадите много времени для одних и тех же подмножеств: во избежание заметок, которые могут потребовать много времени из-за поиска карт и из-за нехватки памяти, вы может генерировать подмножества в этой манере:
GetAllSubsets(List objects) {
List generated = {};
GetAllSubsets(generated, [], objects);
return generated;
}
GetAllSubsets(List subsetGenerated, List objectFixed, List objectsToFix) {
GetAllSubsets(subsetGenerated, objectFixed, objectsToFix.sublist(1, objectsToFix.length());
if (satisfy(toCheck = objectsFixed.add(objectsToFix.get(0)))) {
subsetGenerated.add(toCheck);
GetAllSubsets(subsetGenerated, toCheck, objectsToFix.sublist(1, objectsToFix.length());
}
}
В самом деле, подмножество, добавленное в первом вызове GetAllSubsets не имеет первый элемент objectsToFix, где подмножество добавленного второго вызова (если условие обрезки не нарушается) имеют этот элемент, поэтому пересечение двух наборов подмножеств порождено.
Не имеет смысла перебирать все наборы; если сумма (x, y) больше 100, нет необходимости проверять любое оставшееся подмножество с x, y! (Например: (40,79,50) имеет сумму больше 100, поэтому нет необходимости проверять (40,79,50,1), (40,79,50,66,1) и т. Д. – ooboo
Но это только один пример возможных условий. Что, если условие состоит в том, что сумма меньше 5050 (что составляет сумму от 1 до 100)? Тогда * все * подмножества будут удовлетворять условию. –
Но тот факт, что, в худшем случае вы получите O (2^n). Сложность времени не должна останавливать нас для поиска хорошей эвристики для решения проблемы. – akappa