$title Non-transitive Dice Design (DICE,SEQ=176) $onText Probabilistic dice - an example of a non-transitive relation. We want to design a set of dice with an integer number on each face such that on average dice1 beats dice2, and dice2 on average beats dice3 etc, but diceN has to beat dice1. MIP codes behave very erratic on such a problem and slight reformulations can result in dramatic changes in performance. Also note the face value will be integers automatically. Gardner, M, Scientific American. Robert A Bosch, Mindsharpener, Optima, MP Society Newsletter, Vol 70, June 2003, page 8-9 Robert A Bosch, Monochromatic Squares, Optima, MP Society Newsletter, Vol 71, March 2004, page 6-7 Keywords: mixed integer linear programming, dice designment, mathematics, nontransitive dice $offText $eolcom // Set f 'faces on a dice' / face1*face6 / dice 'number of dice' / dice1*dice3 /; Scalar flo 'lowest face value' / 1 / fup 'highest face value' wn 'wins needed - possible bound'; fup = card(dice)*card(f); wn = floor(0.5*sqr(card(f))) + 1; Alias (f,fp), (dice,dicep); Variable wnx 'number of wins' fval(dice,f) 'value of dice - will be integer' comp(dice,f,fp) 'one if f beats fp'; Binary Variable comp; fval.lo(dice,f) = flo; fval.up(dice,f) = fup; fval.fx("dice1","face1") = flo; Equation eq1(dice) 'count the wins' eq3(dice,f,fp) 'definition of non-transitive relation' eq4(dice,f) 'different face values for a single dice'; eq1(dice).. sum((f,fp), comp(dice,f,fp)) =e= wnx; eq3(dice,f,fp).. fval(dice,f) + (fup - flo)*(1 - comp(dice,f,fp)) =g= fval(dice++1,fp) + 1; eq4(dice,f-1).. fval(dice,f - 1) + 1 =l= fval(dice,f); Model xdice / all /; $if set nosolve $exit set s solvers / cplex, xpress, lindo /; parameter h(s) jobhandle; xdice.optcr = 0; xdice.reslim = 10; *change solveLink to solve simultaneously with different solvers xdice.solveLink = %solveLink.AsyncGrid%; xdice.limCol = 0; xdice.limRow = 0; xdice.solPrint = %solPrint.Quiet%; parameter rep(*,*) report parameter; OPTION MIP=cplex; solve xdice using mip max wnx; h('cplex') = xdice.handle; OPTION MIP=xpress; solve xdice using mip max wnx; h('xpress') = xdice.handle; OPTION MIP=lindo; solve xdice using mip max wnx; h('lindo') = xdice.handle; * collection loop repeat loop(s$handlecollect(h(s)), rep(s,'objVal') = xdice.objVal; rep(s,'time') = xdice.resusd; rep(s,'solvestat') = xdice.solveStat; rep(s,'modelstat') = xdice.modelStat; display$handledelete(h(s)) 'trouble deleting handles'; h(s) = 0; // indicate that we have loaded the solution ); display$sleep(card(h)*0.2) 'was sleeping for some time'; until card(h) = 0 or timeelapsed > 20; // wait until all models are loaded display rep; $exit abort$(xdice.modelstat<>%modelstat.Optimal% and xdice.modelstat<>%modelstat.integerSolution%) 'no integer solution for xdice';