2

This code piece in AMPL solves correctly the pair matching algorithm:

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 .;

This code works smoothly, but it is cumbersome because one has to declare 2 times what student tuples are valid and a value associated with that tuples.

Other question shows an alternative syntax (showed below) for that kind of situation in an answer. The same syntax is showed in a 2011 paper from Darin England from University of Minnesota (Mathematical programming formulations using AMPL) on page 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 .;

However, its generates an error in an updated AMPL version:

malformed header: extra ':' (last colon)

Is there some solution for defining set tuples and values of set tuples in just one declaration?

Paulo Buchsbaum
  • 2,471
  • 26
  • 29

2 Answers2

1

Is there some solution for defining set tuples and values of set tuples in just one declaration?

The sparse version you posted works for me; initially I got an error message "pair is not a set" but this was due to a case mismatch with "Pair"; once I fixed that, it did exactly what it ought. I couldn't reproduce the error you mention. Complete working code:

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 .;

(using AMPL 3.1.0.201510231950 if that makes a difference)

Other options for sparse data input:

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

Alternately:

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

I never did figure out whether it's possible to do it in a 2-D table layout like the code you posted; that would be more readable for small data sets but I mostly work with large ones.

You can also eliminate the duplication of students by declaring Pair as a set of pairs, and then defining Student as the set of all values that appear as either member of a tuple in Pair:

set Pair dimen 2;
param Value{Pair};

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

Then define Pair and Value as above, and Student is derived from Pair.

  • Yes, explicit tuple listing works and it's smart define Students indirectly. I understand that 2D syntax just fit small problems, but it's intriguing that a paper shows a syntax that simply does not work – Paulo Buchsbaum May 03 '18 at 14:42
  • I've sent this syntax issue for AMPL support they have answered 2 times, but I think that just now that have understood my doubt. – Paulo Buchsbaum May 03 '18 at 14:56
  • 1
    @PauloBuchsbaum I didn't test the version you posted before writing my answer, but I gave it a try this morning, and the only problem I had was with a case-sensitive set name (see edit to my answer). Once I fixed that, it seemed to work fine. So maybe it did work for the author of the paper. – GB supports the mod strike May 04 '18 at 00:30
  • Surprisingly AMPL support have answered me and gave a good syntax workaround (I've posted a answer below). My version should be more updaded than yours. – Paulo Buchsbaum May 04 '18 at 01:00
  • @PauloBuchsbaum huh, so it was a new bug in AMPL and not in the code! Interesting that nobody had reported it until now. – GB supports the mod strike May 04 '18 at 01:53
1

Tonight the AMPL support gave me a answer.

I'm quite surprised by the efficiency of AMPL support team!

Using Windows, We found that AMPL version 20171122 and later reject the user's examples with the "malformed header" message, but versions 20171103 and earlier accept the examples (including perfectEr.mod). We have been working to fix the problem. Meanwhile, a workaround is to replace "param: Pair: value: . . ." by "param: Pair: value [,]: . . .".

I've tested it and it works in my AMPL version. I only have added [*.*] after param: Pair: value (Line 23) and before colon (:). Everything works smoothly.

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
Paulo Buchsbaum
  • 2,471
  • 26
  • 29