AMPL: редкий синтаксис - PullRequest
0 голосов
/ 02 мая 2018

Этот фрагмент кода в AMPL правильно решает алгоритм сопоставления пар:

set Student;.
        # student tuples inside Student x Student
set Pair within {Student, Student}; 

       # sparse value in that tuples    
param value {Pair};

var x {Pair} binary;  # decision var

maximize total_value: sum {(i,j) in Pair} value[i,j] * x[i,j];

s.t. perfect_match {i in Student}:  # constraint
sum {(i,j) in Pair} x[i,j] + sum {(j,i) in Pair} x[j,i] = 1;

data;

set Student := A  B  C  D  E  F G H I J;

# sparse set of student tuples   
set Pair:  A  B  C  D  E  F G H I J :=  
A  -  -  -  -  -  - - - - -
B  +  -  -  -  -  - - - - -
C  +  +  -  -  -  - - - - -
D  +  +  +  -  -  - - - - -
E  +  +  +  +  -  - - - - -
F  +  +  +  +  +  - - - - -
G  +  +  +  +  +  + - - - -
H  +  +  +  +  +  + + - - -
I  +  +  +  +  +  + + + - -
J  +  +  +  +  +  + + + + -;

# sparse matrix with scores
param value:  A  B  C  D  E  F G H I J :=  
A  .  .  .  .  .  . . . . .
B  3  .  .  .  .  . . . . .
C  5  8  .  .  .  . . . . .
D  1 -4  7  .  .  . . . . .
E  2 -1  9  2  .  . . . . .
F  2  5  3  2  9  . . . . .
G  8  2  1  1  3 -2 . . . .
H  2  3  3  4  5  1 1 . . .
I 13 -1  3  4  4 -5 2 2 . .
J  1  2  6  6  7 -4 5 6 1 .;

Этот код работает без сбоев, но он громоздок, потому что нужно 2 раза объявить, какие кортежи учащихся допустимы, и значение, связанное с этими кортежами.

Другой вопрос показывает альтернативный синтаксис (показан ниже) для такой ситуации в ответе. Тот же синтаксис показан в статье Дарина, Англия, Университет Миннесоты, 2011 г. ( Формулировки математического программирования с использованием AMPL ) на стр. 5.

# sparse matrix with scores
param: pair: value:  A  B  C  D  E  F G H I J :=  
A  .  .  .  .  .  . . . . .
B  3  .  .  .  .  . . . . .
C  5  8  .  .  .  . . . . .
D  1 -4  7  .  .  . . . . .
E  2 -1  9  2  .  . . . . .
F  2  5  3  2  9  . . . . .
G  8  2  1  1  3 -2 . . . .
H  2  3  3  4  5  1 1 . . .
I 13 -1  3  4  4 -5 2 2 . .
J  1  2  6  6  7 -4 5 6 1 .;

Однако в обновленной версии AMPL выдается ошибка:

malformed header: extra ':' (last colon)

Есть ли какое-то решение для определения наборов кортежей и значений наборов кортежей в одном объявлении?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Сегодня вечером поддержка AMPL дала мне ответ.

Я очень удивлен эффективностью команды поддержки AMPL!

Используя Windows, мы обнаружили, что AMPL версии 20171122 и более поздние отклоняют примеры пользователей с сообщением «неправильный заголовок», но версии 20171103 и ранее принимают примеры (включая perfectEr.mod). Мы работали, чтобы решить проблему. Между тем, обходной путь к заменить "param: Pair: value:..." by "param: Pair: value [, ]:. "..

Я протестировал его, и он работает в моей версии AMPL. Я добавил [*.*] только после param: Pair: value (строка 23) и перед двоеточием (:). Все работает плавно.

reset;
set Student;
set Pair within {Student, Student}; # Student cross Student;

param value {Pair};

# Decision Variable
var x {Pair} binary;

# Objective
maximize total_value: sum {(i,j) in Pair} value[i,j] * x[i,j];

# Constraint
s.t. perfect_match {i in Student}:
sum {(i,j) in Pair} x[i,j] + sum {(j,i) in Pair} x[j,i] = 1;

data;

# Students names
set Student := A  B  C  D  E  F G H I J;  

# affinity in defined tuples (Pair)
param: Pair: value [*,*]: 
   A  B  C  D  E  F G H I J :=   
A  .  .  .  .  .  . . . . .
B  3  .  .  .  .  . . . . .
C  5  8  .  .  .  . . . . .
D  1 -4  7  .  .  . . . . .
E  2 -1  9  2  .  . . . . .
F  2  5  3  2  9  . . . . .
G  8  2  1  1  3 -2 . . . .
H  2  3  3  4  5  1 1 . . .
I 13 -1  3  4  4 -5 2 2 . .
J  1  2  6  6  7 -4 5 6 1 .;

option solver CPLEX;
solve;
option omit_zero_rows 1;
display x
0 голосов
/ 03 мая 2018

Есть ли какое-то решение для определения набора кортежей и значений набора кортежи только в одной декларации?

Редкая версия, которую вы разместили, работает для меня; изначально я получил сообщение об ошибке «пара не является набором», но это было связано с несовпадением регистра с «парой»; как только я это исправил, он сделал именно то, что должен. Я не мог воспроизвести ошибку, которую вы упоминаете. Полный рабочий код:

set Student;
        # student tuples inside Student x Student
set Pair within {Student, Student}; 

       # sparse value in that tuples    
param value {Pair};

data;

set Student := A  B  C  D  E  F G H I J;

param: Pair: value:  A  B  C  D  E  F G H I J :=  
A  .  .  .  .  .  . . . . .
B  3  .  .  .  .  . . . . .
C  5  8  .  .  .  . . . . .
D  1 -4  7  .  .  . . . . .
E  2 -1  9  2  .  . . . . .
F  2  5  3  2  9  . . . . .
G  8  2  1  1  3 -2 . . . .
H  2  3  3  4  5  1 1 . . .
I 13 -1  3  4  4 -5 2 2 . .
J  1  2  6  6  7 -4 5 6 1 .;

(используя AMPL 3.1.0.201510231950, если это имеет значение)

Другие опции для разреженного ввода данных:

param: pair: value :=
A B 3
A C 5
B C 8
...
;

С другой стороны:

param: pair: value :=
[A,*]
B 3
C 5
D 1
...
J 1
[B,*]
C 8
D -4
...
J 2
...
;

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

Вы также можете устранить дублирование учеников, объявив «Пара» как набор пар, а затем определив «Студент» как набор всех значений, которые отображаются в качестве одного из членов кортежа в паре:

set Pair dimen 2;
param Value{Pair};

set Students := setof{(i,j) in Pair} i union setof{(i,j) in Pair} j;

Затем определите Pair и Value, как указано выше, и Student получен из Pair.

...