CPLEX OPL: принудительно установить набор переменных решения

Любой разумный способ заставить набор переменных решения быть равными?

(Если не стесняйтесь использовать решение)

Объявления

Учитывая следующий набор:

ID1     | ID2
------- | -------
A       | AA
B       | AA
C       | BB
C       | AA
C       | CC
D       | CC

например, инициализируется в OPL

//Set ID
tuple ObjectID{
    string ID1;
    string ID2;
    }
{ObjectID} ID = {
    <"A", "AA">,
    <"B", "AA">,
    <"C", "BB">,
    <"C", "AA">,
    <"C", "CC">,
    <"D", "CC">,
    };

И переменная решения x[ID] будет объявлена ​​в OPL как

dvar int+ x[ID]

Эта проблема

Решающая переменная x[ID] должна быть равна, если ID1 равен для всех ID2.

Пример:

x[<"C", "BB">] == x[<"C", "AA">] == x[<"C", "CC">]

Текущее решение

Попарное сравнение всех дваров с одинаковыми ID1 и разными ID2.

forall(
   id_1 in ID, id_2 in ID:
      id_1.ID1 == id_2.ID1 &&
      id_1.ID2 != id_2.ID2
   )
x[id_1] == x[id_2];

1 ответ

Решение

Первым улучшением было бы использовать упорядоченное деление на 2 числа ограничений равенства:

forall(ordered id_1,id_2 in ID :id_1.ID1 == id_2.ID1 )
     x[id_1] == x[id_2];

и второе улучшение может состоять в том, чтобы перейти от (n-1)*n/2 ограничений к (n-1) ограничениям

//Set ID
tuple ObjectID{
    string ID1;
    string ID2;
    }
{ObjectID} ID = {
    <"A", "AA">,
    <"B", "AA">,
    <"C", "BB">,
    <"C", "AA">,
    <"C", "CC">,
    <"D", "CC">
    };

dvar int+ x[ID];

{string} Id1s={i.ID1 | i in ID};
{string} Id2PerId1[id1 in Id1s]={i.ID2 | i in ID : i.ID1==id1};



subject to
{


forall(id1 in Id1s) forall(id2 in Id2PerId1[id1] diff     {last(Id2PerId1[id1])})
   x[<id1,id2>] == x[<id1,next(Id2PerId1[id1],id2)>];


  }

`

Другие вопросы по тегам