Комбинаторное наилучшее совпадение

Скажем, у меня есть структура данных Group, которая содержит список объектов Element, так что каждая группа имеет уникальный набор элементов .:

public class Group
{
  public List<Element> Elements;
}

и скажем, у меня есть список популяций, которым требуются определенные элементы, таким образом, чтобы у каждой популяции был уникальный набор необходимых элементов:

public class Population
{
  public List<Element> RequiredElements;
}

У меня есть неограниченное количество каждой определенной группы, т.е. они не потребляются населением.

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

Например: у меня есть население, которому нужны древесина, сталь, зерно и уголь. Доступны только группы {дерево, травы}, {сталь, уголь, масло}, {зерно, сталь} и {травы, мясо}.

Последняя группа - {травы, мясо} совсем не нужна моему населению, поэтому не используется. Все остальные необходимы, но травы и масло не требуются, поэтому они тратятся впустую. Кроме того, в минимальном наборе сталь существует дважды, поэтому одна партия стали также тратится впустую. У наилучшего соответствия в этом примере потери равны 3.

Итак, для нескольких сотен Population объектов мне нужно найти наилучшее соответствие минимальных потерь и вычислить, сколько элементов теряется.

Как мне вообще начать это решать? Как только я найду совпадение, подсчет потерь станет тривиальным делом. Во-первых, найти совпадение сложно. Я мог бы перечислить все возможности, но с несколькими тысячами популяций и многими сотнями групп это довольно трудная задача. Особенно с учетом того, что все это находится внутри каждой итерации алгоритма имитации отжига.

Мне интересно, могу ли я сформулировать все это как программу со смешанными целыми числами и вызывать решатель, такой как GLPK, на каждой итерации.

Надеюсь, я правильно объяснил проблему. Я могу прояснить все, что неясно.


Вот моя бинарная программа, для тех, кому интересно ...

x - вектор решения, элемент {0,1}, который говорит, что рассматриваемая популяция получает / не получает от группы i. Для каждой группы есть запись.

b - вектор-столбец, элемент {0,1}, который говорит, какие ресурсы данной популяции нужны / не нужны. Для каждого ресурса есть запись.

A - это матрица, элемент {0,1}, которая говорит, какие ресурсы в каких группах.

Программа:

Свернуть: ((Ax - b) '* 1-вектор) + (x' * 1-вектор);

При условии: Ax> = b;

Ограничение просто говорит, что все необходимые ресурсы должны быть удовлетворены. Цель состоит в том, чтобы свести к минимуму все лишнее и общее количество используемых групп. (т.е. 0 превышений при использовании 1 группы лучше, чем избыток 0 при использовании 5 групп).


person Ozzah    schedule 09.10.2012    source источник
comment
Сколько существует уникальных типов групп или, скорее, каково максимальное количество уникальных групп, которые могут существовать? Какое максимальное количество элементов может использовать каждая популяция? Если эти числа малы, то вы можете подобрать решение путем перебора всех возможных уникальных комбинаций групп и отслеживания наименьших потерь.   -  person Bob Bryan    schedule 09.10.2012
comment
Как я сказал в своем вопросе, есть тысячи каждого типа. Более того, мне нужно решать эту проблему точно для каждой итерации моего алгоритма SA.   -  person Ozzah    schedule 10.10.2012


Ответы (3)


Вы можете сформулировать целочисленную программу для каждой популяции P следующим образом. Используйте двоичную переменную x j, чтобы указать, выбрана ли группа j или нет. Пусть A будет двоичной матрицей, такой что A ij равно 1 тогда и только тогда, когда элемент i присутствует в группе j. Тогда целочисленная программа:

мин E i, j (x j A ij)

s.t. E j x j A ij> = 1 для всех i в P.

x j = 0, 1 для всех j.

Обратите внимание, что вы можете получить минимальные потери, вычтя |P| из оптимального решения вышеуказанного IP.

person krjampani    schedule 09.10.2012
comment
Спасибо, у меня уже есть формулировка IP, которая решает эту проблему, но я надеялся, что мне не придется вызывать решатель на каждой итерации моего SA :( - person Ozzah; 09.10.2012
comment
Я не думаю, что можно избежать вызова IP на каждой итерации, когда популяции и группы произвольны. - person krjampani; 09.10.2012

Вы имеете в виду проблему максимального соответствия?

Вам необходимо построить двудольный граф, где одна сторона - это ваши популяции, а другая - группы. , и ребро существует между группой A и популяцией B, если оно есть в своем наборе.

Чтобы найти максимальное соответствие ребер, вы можете легко использовать алгоритм Куна, который подробно описан здесь, в TopCoder.
Но если вы хотите найти минимальное множество ребер с преобладанием ребер (набор минимальных ребер, покрывающих все вершины), проблема становится NP- сложно и не может быть решен за полиномиальное время.

person dreamzor    schedule 09.10.2012
comment
Боюсь, что оба ваших подхода к моделированию не помогут решить данную проблему. - person Reinhard; 10.10.2012

Взгляните на проблему с укрытием взвешенного набора, я думаю, это именно то, что вы описали выше. Базовое описание (невзвешенной) проблемы можно найти здесь.

Нахождение минимальных потерь, как вы определили выше, эквивалентно поиску такого покрытия множества, при котором сумма мощностей множеств покрытия минимальна. Следовательно, вес каждого набора (= группы элементов) должен быть определен равным его мощности.

Поскольку даже невзвешенная проблема с заданным покрытием является NP-полной, маловероятно, что существует эффективный алгоритм для ваших экземпляров проблемы. Может быть, будет достаточно хорошего жадного алгоритма аппроксимации или вашей цели? Поиск в Google обложки взвешенного набора дает несколько многообещающих результатов, например этот скрипт.

person Reinhard    schedule 10.10.2012