(!****************************************************** Mosel Example Problems ====================== file inscribedsquare_graph.mos `````````````````````````````` Computes a maximal inscribing square for the curve (sin(t)*cos(t), sin(t)*t), t in [-pi,pi] Source: https://www.minlplib.org/inscribedsquare01.html t1..t4 are the four values of the parameter t. x and y are the (x,y) coordinates of the first corner of the square. (vx, vy) is a vector pointing to a second vertex, all the other vertices are given by a combination of these four values. The length of the vector (vx,vy) is exactly the side length of the square, which we are maximizing, that is, the square of it, to keep it nicer. - Graphical representation of results - (c) 2023 Fair Isaac Corporation author: S. Heipcke, July 2023 *******************************************************!) model "inscribedsquare" uses "mmxnlp", "mmsvg" parameters ALG=2 ! Solver choice: 1: global, 2: SLP, 3: Knitro end-parameters declarations t1,t2,t3,t4,x,y,vx,vy: mpvar end-declarations ! Variable bounds t1 >= -3,142; t1 <= 3,142; t2 >= -3,142; t2 <= 3,142; t3 >= -3,142; t3 <= 3,142; t4 >= -3,142; t4 <= 3,142; x is_free y is_free (! Optionally, set initial values: setinitval(t1, -3,142) setinitval(t2, -1,571) setinitval(t3, 1,571) setinitval(t4, 1,571) setinitval(x, 0) setinitval(y, 0) setinitval(vx, 1) setinitval(vy, 1) !) Obj:= vx^2 + vy^2; ! Constraints E2:= sin(t1)*cos(t1) - x = 0; E3:= sin(t1)*t1 - y = 0; E4:= sin(t2)*cos(t2) - x - vx = 0; E5:= sin(t2)*t2 - y - vy = 0; E6:= sin(t3)*cos(t3) - x + vy = 0; E7:= sin(t3)*t3 - y - vx = 0; E8:= sin(t4)*cos(t4) - x - vx + vy = 0; E9:= sin(t4)*t4 - y - vx - vy = 0; setparam("XNLP_VERBOSE",true) ! Uncomment to see detailed output case ALG of 1: writeln("Using global solver") 2: do writeln("Using SLP as local solver") ! Use multi-start heuristic addmultistart("random points", XNLP_MSSET_INITIALVALUES, 100) setparam("XPRS_NLPSOLVER", 1) ! Use a local NLP solver setparam("XNLP_SOLVER", 0) ! Select SLP as local solver end-do 3: do writeln("Using Knitro as local solver") ! Use multi-start heuristic addmultistart("random points", XNLP_MSSET_INITIALVALUES, 100) setparam("XPRS_NLPSOLVER", 1) ! Use a local NLP solver setparam("XNLP_SOLVER", 1) ! Select Knitro as local solver end-do end-case maximize(Obj) writeln("Solution value: ", getobjval) writeln("Corner point: ", x.sol, ",", y.sol) writeln("Side vector: ", vx.sol, " ", vy.sol) writeln("t=", t1.sol, " ", t2.sol, " ", t3.sol, " ", t4.sol) ! **** Display the solution as user graph **** declarations RT,P: list of real end-declarations ! Set the size of the displayed graph svgsetgraphscale(100) svgsetgraphlabels("x","y") svgsetgraphviewbox(-1,0,2.5,2.5) ! Draw the graph of the curve svgaddgroup("G", "Enclosing graph") STEP:=100 OFFSET:=0,75 ! Translation offset to avoid negative coordinates in SVG forall(i in 0..STEP) RT+=[-M_PI+i/STEP*2*M_PI] svgaddline(sum(t in RT) [sin(t)*cos(t)+OFFSET, sin(t)*t]) ! Draw the solution square svgaddgroup("S", "Square") P:=[x.sol+OFFSET, y.sol, x.sol+vx.sol+OFFSET, y.sol+vy.sol, x.sol+vx.sol-vy.sol+OFFSET, y.sol+vy.sol+vx.sol, x.sol-vy.sol+OFFSET, y.sol+vx.sol] (! Same as: P:=sum(t in [t1.sol,t2.sol,t4.sol,t3.sol]) [sin(t)*cos(t)+OFFSET, sin(t)*t] !) writeln(P) svgaddpolygon(P) svgaddtext(0.15,2.25,"Solution with " + if(ALG=1, "Global", if(ALG=2, "SLP", "Knitro")) + ": "+textfmt(getobjval,6,5)) svgsetstyle(svggetlastobj, SVG_COLOR, SVG_BLACK) svgsave("inscribedsq"+ALG+".svg") svgrefresh svgwaitclose("Close browser window to terminate model execution.", 1) end-model