public static void Main()
    {
        const double
            infinity = 0;

        mosek.boundkey[] bkc = new mosek.boundkey[] {
            mosek.boundkey.up, mosek.boundkey.up,
            mosek.boundkey.up, mosek.boundkey.fx,
            mosek.boundkey.fx, mosek.boundkey.fx,
            mosek.boundkey.fx
        };

        mosek.boundkey[] bkx = new mosek.boundkey[] {
            mosek.boundkey.lo, mosek.boundkey.lo,
            mosek.boundkey.lo, mosek.boundkey.lo,
            mosek.boundkey.lo, mosek.boundkey.lo,
            mosek.boundkey.lo
        };

        int[]    ptrb = new int[] { 0, 2, 4, 6, 8, 10, 12 };
        int[]    ptre = new int[] { 2, 4, 6, 8, 10, 12, 14 };
        int[]    sub  = new int[] { 0, 3, 0, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6 };
        double[] blc  = new double[] {
            -infinity, -infinity,
            -infinity, 800, 100, 500, 500
        };

        double[] buc = new double[] { 400, 1200, 1000, 800, 100, 500, 500 };
        double[] c   = new double[] { 1.0, 2.0, 5.0, 2.0, 1.0, 2.0, 1.0 };
        double[] blx = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
        double[] bux = new double[] { infinity,
                                      infinity,
                                      infinity,
                                      infinity,
                                      infinity,
                                      infinity,
                                      infinity };

        double[] val = new double[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                                      1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };

        int numcon = 7; /* Number of constraints.             */
        int numvar = 7; /* Number of variables.               */

        try
        {
            using (mosek.Env env = new mosek.Env())
            {
                using (mosek.Task task = new mosek.Task(env))
                {
                    // Directs the log task stream to the user specified
                    // method task_msg_obj.streamCB
                    task.set_Stream(mosek.streamtype.log, new msgclass("[task]"));

                    task.inputdata(numcon, numvar,
                                   c,
                                   0.0,
                                   ptrb,
                                   ptre,
                                   sub,
                                   val,
                                   bkc,
                                   blc,
                                   buc,
                                   bkx,
                                   blx,
                                   bux);

                    /* A maximization problem */
                    task.putobjsense(mosek.objsense.minimize);

                    try
                    {
                        task.optimize();
                    }
                    catch (mosek.Warning w)
                    {
                        Console.WriteLine("Mosek warning:");
                        Console.WriteLine(w.Code);
                        Console.WriteLine(w);
                    }


                    /* Analyze upper bound on c1 and the equality constraint on c4 */
                    int[]        subi  = new int [] { 0, 3 };
                    mosek.mark[] marki = new mosek.mark[] { mosek.mark.up,
                                                            mosek.mark.up };

                    /* Analyze lower bound on the variables x12 and x31 */
                    int[]        subj  = new int [] { 1, 4 };
                    mosek.mark[] markj = new mosek.mark[] { mosek.mark.lo,
                                                            mosek.mark.lo };

                    double[] leftpricei  = new  double[2];
                    double[] rightpricei = new  double[2];
                    double[] leftrangei  = new  double[2];
                    double[] rightrangei = new  double[2];
                    double[] leftpricej  = new  double[2];
                    double[] rightpricej = new  double[2];
                    double[] leftrangej  = new  double[2];
                    double[] rightrangej = new  double[2];


                    task.primalsensitivity(subi,
                                           marki,
                                           subj,
                                           markj,
                                           leftpricei,
                                           rightpricei,
                                           leftrangei,
                                           rightrangei,
                                           leftpricej,
                                           rightpricej,
                                           leftrangej,
                                           rightrangej);

                    Console.Write("Results from sensitivity analysis on bounds:\n");

                    Console.Write("For constraints:\n");
                    for (int i = 0; i < 2; ++i)
                    {
                        Console.Write(
                            "leftprice = {0}, rightprice = {1},leftrange = {2}, rightrange ={3}\n",
                            leftpricei[i], rightpricei[i], leftrangei[i], rightrangei[i]);
                    }

                    Console.Write("For variables:\n");
                    for (int i = 0; i < 2; ++i)
                    {
                        Console.Write(
                            "leftprice = {0}, rightprice = {1},leftrange = {2}, rightrange ={3}\n",
                            leftpricej[i], rightpricej[i], leftrangej[i], rightrangej[i]);
                    }


                    double[] leftprice  = new  double[2];
                    double[] rightprice = new  double[2];
                    double[] leftrange  = new  double[2];
                    double[] rightrange = new  double[2];
                    int[]    subc       = new int[] { 2, 5 };

                    task.dualsensitivity(subc,
                                         leftprice,
                                         rightprice,
                                         leftrange,
                                         rightrange
                                         );

                    Console.Write("Results from sensitivity analysis on objective coefficients:");

                    for (int i = 0; i < 2; ++i)
                    {
                        Console.Write(
                            "leftprice = {0}, rightprice = {1},leftrange = {2}, rightrange = {3}\n",
                            leftprice[i], rightprice[i], leftrange[i], rightrange[i]);
                    }
                }
            }
        }
        catch (mosek.Exception e)
        {
            Console.WriteLine(e.Code);
            Console.WriteLine(e);
            throw;
        }
    }
Exemple #2
0
        public static void Main()
        {
            const int numcon = 1;
            const int numvar = 3;

            // Since the value infinity is never used, we define
            // 'infinity' symbolic purposes only
            double infinity = 0;

            mosek.boundkey bkc = mosek.boundkey.fx;
            double         blc = 1.0;
            double         buc = 1.0;

            mosek.boundkey[] bkx = { mosek.boundkey.fr,
                                     mosek.boundkey.fr,
                                     mosek.boundkey.fr };
            double[]         blx = { -infinity,
                                     -infinity,
                                     -infinity };
            double[]         bux = { +infinity,
                                     +infinity,
                                     +infinity };

            double[] c = { 1.0,
                           1.0,
                           0.0 };

            double[] a    = { 1.0, 1.0, 1.0 };
            int[]    asub = { 0, 1, 2 };
            int[]    csub = new int[3];

            // Make mosek environment.
            using (mosek.Env env = new mosek.Env())
            {
                // Create a task object.
                using (mosek.Task task = new mosek.Task(env, 0, 0))
                {
                    // Directs the log task stream to the user specified
                    // method msgclass.streamCB
                    task.set_Stream(mosek.streamtype.log, new msgclass(""));

                    /* Append 'numcon' empty constraints.
                     * The constraints will initially have no bounds. */
                    task.appendcons(numcon);

                    /* Append 'numvar' variables.
                     * The variables will initially be fixed at zero (x=0). */
                    task.appendvars(numvar);

                    /* Set up the linear part of the problem */
                    task.putcslice(0, numvar, c);
                    task.putarow(0, asub, a);
                    task.putconbound(0, bkc, blc, buc);
                    task.putvarboundslice(0, numvar, bkx, blx, bux);

                    /* Define the exponential cone */
                    csub[0] = 0;
                    csub[1] = 1;
                    csub[2] = 2;
                    task.appendcone(mosek.conetype.pexp,
                                    0.0, /* For future use only, can be set to 0.0 */
                                    csub);

                    task.putobjsense(mosek.objsense.minimize);
                    task.optimize();

                    // Print a summary containing information
                    // about the solution for debugging purposes
                    task.solutionsummary(mosek.streamtype.msg);

                    mosek.solsta solsta;
                    /* Get status information about the solution */
                    task.getsolsta(mosek.soltype.itr, out solsta);

                    double[] xx = new double[numvar];

                    task.getxx(mosek.soltype.itr, // Basic solution.
                               xx);

                    switch (solsta)
                    {
                    case mosek.solsta.optimal:
                        Console.WriteLine("Optimal primal solution\n");
                        for (int j = 0; j < numvar; ++j)
                        {
                            Console.WriteLine("x[{0}]: {1}", j, xx[j]);
                        }
                        break;

                    case mosek.solsta.dual_infeas_cer:
                    case mosek.solsta.prim_infeas_cer:
                        Console.WriteLine("Primal or dual infeasibility.\n");
                        break;

                    case mosek.solsta.unknown:
                        Console.WriteLine("Unknown solution status.\n");
                        break;

                    default:
                        Console.WriteLine("Other solution status");
                        break;
                    }
                }
            }
        }
        public void computeForceDiagram(List<leaf> _listLeaf, List<node> _listNode)
        {
            //variable settings
            int numvar = _listNode.Count * 2;
            int numcon = 0;
            double infinity = 0;
            numcon += _listNode.Count;  //finite element matrix

            foreach (var leaf in _listLeaf)
            {
                leaf.conOffset = numcon;
                leaf.varOffset = numvar;
                numcon += leaf.tuples.Length * 1; //grad(detF)dx>-detF
            }
            mosek.boundkey[] bkx = new mosek.boundkey[numvar];
            double[] blx = new double[numvar];
            double[] bux = new double[numvar];
            for (int i = 0; i < _listNode.Count; i++)
            {
                if (_listNode[i].forceNodeType== node.type.fx)
                {
                    bkx[i * 2 + 0] = mosek.boundkey.fx;
                    blx[i * 2 + 0] = 0;// _listNode[i].X;
                    bux[i * 2 + 0] = 0;//_listNode[i].X;
                    bkx[i * 2 + 1] = mosek.boundkey.fx;
                    blx[i * 2 + 1] = 0;//_listNode[i].Y;
                    bux[i * 2 + 1] = 0;//_listNode[i].Y;
                }
                else
                {
                    bkx[i * 2 + 0] = mosek.boundkey.fr;
                    blx[i * 2 + 0] = -infinity;
                    bux[i * 2 + 0] = infinity;
                    bkx[i * 2 + 1] = mosek.boundkey.fr;
                    blx[i * 2 + 1] = -infinity;
                    bux[i * 2 + 1] = infinity;
                }
            }
            for (int t = 0; t < 10; t++)
            {
                init(_listLeaf);
                double[] x = new double[_listNode.Count * 2];
                foreach (var leaf in _listLeaf)
                {
                    for (int j = 0; j < leaf.nV; j++)
                    {
                        for (int i = 0; i < leaf.nU; i++)
                        {
                            int indexX = leaf.globalIndex[i + j * leaf.nU] * 2 + 0;
                            int indexY = leaf.globalIndex[i + j * leaf.nU] * 2 + 1;
                            var Q = leaf.forceSrf.Points.GetControlPoint(i, j);
                            x[indexX] = Q.Location.X;
                            x[indexY] = Q.Location.Y;
                        }
                    }

                }
                using (mosek.Env env = new mosek.Env())
                {
                    // Create a task object.
                    using (mosek.Task task = new mosek.Task(env, 0, 0))
                    {
                        // Directs the log task stream to the user specified
                        // method msgclass.streamCB
                        task.set_Stream(mosek.streamtype.log, new msgclass(""));
                        task.appendcons(numcon);
                        task.appendvars(numvar);
                        for (int j = 0; j < numvar; ++j)
                        {
                            task.putvarbound(j, bkx[j], blx[j], bux[j]);
                        }
                        
                        ShoNS.Array.SparseDoubleArray mat = new SparseDoubleArray(_listNode.Count, _listNode.Count * 2);
                        
                        
                        foreach (var leaf in _listLeaf)
                        {
                            foreach (var tup in leaf.tuples)
                            {
                                for(int i = 0; i < tup.nNode; i++)
                                {
                                    int indexI = leaf.globalIndex[tup.internalIndex[i]];
                                    for (int j = 0; j < tup.nNode; j++)
                                    {
                                        int indexJx = leaf.globalIndex[tup.internalIndex[j]] * 2 + 0;
                                        int indexJy = leaf.globalIndex[tup.internalIndex[j]] * 2 + 1;
                                        var d0 = tup.d0;
                                        var d1 = tup.d1;
                                        var G1 = tup.refGi[0];
                                        var G2 = tup.refGi[1];
                                        var val0 = (d0[j] * d1[0][i] * G1[1] + d0[j] * d1[1][i] * G2[1]) * tup.refDv * tup.area;
                                        var val1 = -(d0[j] * d1[0][i] * G1[0] + d0[j] * d1[1][i] * G2[0]) * tup.refDv * tup.area;
                                        mat[indexI, indexJx] += val0;
                                        mat[indexI, indexJy] += val1;
                                    }
                                }
                            }
                        }
                        
                        for (int i = 0; i < _listNode.Count; i++)
                        {
                            var val = 0d;
                            for (int j = 0; j < _listNode.Count * 2; j++)
                            {
                                val += mat[i, j] * x[j];
                            }
                            task.putconbound(i, mosek.boundkey.fx, -val, -val);
                            for (int j = 0; j < _listNode.Count*2; j++)
                            {
                                task.putaij(i, j, mat[i, j]);
                            }
                        }
                        
                        foreach (var leaf in _listLeaf)
                        {
                            int offsetC = 0;
                            foreach (var tup in leaf.tuples)
                            {
                                //compute current detF
                                //x,y; referece, X,Y; forceDiagram
                                var FXx = tup.gi[0][0] * tup.refGi[0][0] + tup.gi[1][0] * tup.refGi[1][0];
                                var FYy = tup.gi[0][1] * tup.refGi[0][1] + tup.gi[1][1] * tup.refGi[1][1];
                                var FXy = tup.gi[0][0] * tup.refGi[0][1] + tup.gi[1][0] * tup.refGi[1][1];
                                var FYx = tup.gi[0][1] * tup.refGi[0][0] + tup.gi[1][1] * tup.refGi[1][0];
                                var detF = FXx * FYy- FXy * FYx;
                                task.putconbound(leaf.conOffset + offsetC, mosek.boundkey.lo, -detF,infinity);
                                var G1 = tup.refGi[0];
                                var G2 = tup.refGi[1];
                                for (int i = 0; i < tup.nNode; i++)
                                {
                                    int indexX = leaf.globalIndex[tup.internalIndex[i]] * 2 + 0;
                                    int indexY = leaf.globalIndex[tup.internalIndex[i]] * 2 + 1;

                                    double val1 = (tup.d1[0][i] * G1[0] + tup.d1[1][i] * G2[0]) * FYy;
                                    double val2 = (tup.d1[0][i] * G1[1] + tup.d1[1][i] * G2[1]) * FYx;

                                    task.putaij(leaf.conOffset + offsetC, indexX, -val2);
                                    val1 = (tup.d1[0][i] * G1[1] + tup.d1[1][i] * G2[1]) * FXx;
                                    val2 = (tup.d1[0][i] * G1[0] + tup.d1[1][i] * G2[0]) * FXy;
                                    task.putaij(leaf.conOffset + offsetC, indexY, val1- val2);
                                }
                                offsetC ++;
                            }
                        }
                        for (int i = 0; i < _listNode.Count; i++)
                        {
                            task.putqobjij(i * 2 + 0, i * 2 + 0, 1);
                            task.putqobjij(i * 2 + 1, i * 2 + 1, 1);
                        }
                        task.optimize();
                        // Print a summary containing information
                        //   about the solution for debugging purposes
                        task.solutionsummary(mosek.streamtype.msg);

                        mosek.solsta solsta;
                        task.getsolsta(mosek.soltype.itr, out solsta);

                        double[] dx = new double[numvar];

                        task.getxx(mosek.soltype.itr, // Basic solution.     
                                        dx);

                        switch (solsta)
                        {
                            case mosek.solsta.optimal:
                                System.Windows.Forms.MessageBox.Show("Optimal primal solution\n");
                                break;
                            case mosek.solsta.near_optimal:
                                System.Windows.Forms.MessageBox.Show("Near Optimal primal solution\n");
                                break;
                            case mosek.solsta.dual_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.prim_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.near_dual_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.near_prim_infeas_cer:
                                System.Windows.Forms.MessageBox.Show("Primal or dual infeasibility.\n");
                                break;
                            case mosek.solsta.unknown:
                                System.Windows.Forms.MessageBox.Show("Unknown solution status\n");
                                break;
                            default:
                                System.Windows.Forms.MessageBox.Show("Other solution status\n");
                                break;

                        }
                        foreach (var leaf in _listLeaf)
                        {
                            for (int j = 0; j < leaf.nV; j++)
                            {
                                for (int i = 0; i < leaf.nU; i++)
                                {
                                    int indexX = leaf.globalIndex[i + j * leaf.nU] * 2 + 0;
                                    int indexY = leaf.globalIndex[i + j * leaf.nU] * 2 + 1;
                                    var Q = leaf.forceSrf.Points.GetControlPoint(i, j);
                                    var P = new Point3d(Q.Location.X + dx[indexX] * 1d, Q.Location.Y + dx[indexY] * 1d, 0);
                                    leaf.forceSrf.Points.SetControlPoint(i, j, P);
                                }
                            }
                        }
                    }
                }
                ExpirePreview(true);
            }
        }
Exemple #4
0
        public void mosek1(List<leaf> _listLeaf, List<branch> _listBranch, Dictionary<string, slice> _listSlice,Dictionary<string,range>_listRange,Dictionary<string,range>_listRangeOpen,Dictionary<string,range> _listRangeLeaf, bool obj, double allow, bool obj2)
        {
            // Since the value infinity is never used, we define
            // 'infinity' symbolic purposes only
            double infinity = 0;
            int[] csub = new int[3];// for cones
            int numvar = 0;
            int numcon = 0;
            foreach (var leaf in _listLeaf)
            {
                leaf.varOffset = numvar;
                leaf.conOffset = numcon;
                numvar += (leaf.nU * leaf.nV) + leaf.r * 4;  //z,H11,H22,H12 mean curvature
                numcon += leaf.r * 4;// H11,H22,H12
                if (obj) numvar += leaf.r * 3; //z,target_z, z-_z
                if (obj) numcon += leaf.r * 2; //z, z-target_z
            }

            foreach (var branch in _listBranch)
            {
                branch.varOffset = numvar;
                branch.conOffset = numcon;
                numvar += branch.N + branch.tuples.Count(); //z,D
                if (branch.branchType == branch.type.kink)
                {
                    numcon += 2 * branch.N;//branch->left and right sides
                }
                else if (branch.branchType == branch.type.reinforce||branch.branchType==branch.type.open)
                {
                    numcon += 1 * branch.N; //z=-ax-by-d
                    numcon += 1 * branch.N; //branch->edge(target)
                }
                else//free
                {
                    numcon += 1 * branch.N; //branch->edge(target)
                }
                numcon += branch.tuples.Count();// D(kink angle)
            }

            foreach (var slice in _listSlice.Values)
            {
                slice.varOffset = numvar;
                slice.conOffset = numcon;
                numvar += 3;  //a,b,d
                if (slice.sliceType == slice.type.fx)
                {
                    numcon++;
                }
            }

            if (obj)
            {
                numvar++;
            }
            //variable settings
            mosek.boundkey[] bkx = new mosek.boundkey[numvar];
            double[] blx = new double[numvar];
            double[] bux = new double[numvar];
            foreach (var leaf in _listLeaf)
            {
                //z
                for (int i = 0; i < leaf.nU * leaf.nV; i++)
                {
                    bkx[i + leaf.varOffset] = mosek.boundkey.fr;
                    blx[i + leaf.varOffset] = -infinity;
                    bux[i + leaf.varOffset] = infinity;
                }
                //H11,H22,H12
                for (int i = 0; i < leaf.r; i++)
                {
                    int n = i * 3 + (leaf.nU * leaf.nV);
                    bkx[n + leaf.varOffset] = mosek.boundkey.fr;
                    blx[n + leaf.varOffset] = -infinity;
                    bux[n + leaf.varOffset] = infinity;
                    bkx[n + 1 + leaf.varOffset] = mosek.boundkey.fr;
                    blx[n + 1 + leaf.varOffset] = -infinity;
                    bux[n + 1 + leaf.varOffset] = infinity;
                    bkx[n + 2 + leaf.varOffset] = mosek.boundkey.fr;
                    blx[n + 2 + leaf.varOffset] = -infinity;
                    bux[n + 2 + leaf.varOffset] = infinity;
                }
                //later mean curvature will be added here
                //
                for (int i = 0; i < leaf.r; i++)
                {
                    int n = i + leaf.r*3+(leaf.nU * leaf.nV);
                    if (leaf.range.rangeType == range.type.lo)
                    {
                        bkx[n + leaf.varOffset] = mosek.boundkey.lo;
                        blx[n + leaf.varOffset] = leaf.range.lb;
                        bux[n + leaf.varOffset] = 0;
                    }
                    else if (leaf.range.rangeType == range.type.up)
                    {
                        bkx[n + leaf.varOffset] = mosek.boundkey.up;
                        blx[n + leaf.varOffset] = 0;
                        bux[n + leaf.varOffset] = leaf.range.ub;
                    }
                    else
                    {
                        bkx[n + leaf.varOffset] = mosek.boundkey.ra;
                        blx[n + leaf.varOffset] = leaf.range.lb;
                        bux[n + leaf.varOffset] = leaf.range.ub;
                    }

                }

                ////////////////
                //target z
                if (obj)
                {
                    //z
                    for (int i = 0; i < leaf.r; i++)
                    {
                        bkx[i + (leaf.nU * leaf.nV) + 4 * leaf.r + leaf.varOffset] = mosek.boundkey.fr;
                        blx[i + (leaf.nU * leaf.nV) + 4 * leaf.r + leaf.varOffset] = 0;
                        bux[i + (leaf.nU * leaf.nV) + 4 * leaf.r + leaf.varOffset] = 0;
                    }
                    //target_z
                    for (int i = 0; i < leaf.r; i++)
                    {
                        bkx[i + (leaf.nU * leaf.nV) + 5 * leaf.r + leaf.varOffset] = mosek.boundkey.fx;
                        //reference multiquadric surface
                        blx[i + (leaf.nU * leaf.nV) + 5 * leaf.r + leaf.varOffset] = globalFunc(leaf.tuples[i].x, leaf.tuples[i].y);
                        bux[i + (leaf.nU * leaf.nV) + 5 * leaf.r + leaf.varOffset] = globalFunc(leaf.tuples[i].x, leaf.tuples[i].y);
                    }
                    //z-target_z
                    for (int i = 0; i < leaf.r; i++)
                    {
                        bkx[i + (leaf.nU * leaf.nV) + 6 * leaf.r + leaf.varOffset] = mosek.boundkey.fr;
                        blx[i + (leaf.nU * leaf.nV) + 6 * leaf.r + leaf.varOffset] = 0;
                        bux[i + (leaf.nU * leaf.nV) + 6 * leaf.r + leaf.varOffset] = 0;
                    }
                }
            }
            foreach(var branch in _listBranch)
            {
                if (branch.branchType == branch.type.reinforce )
                {
                    for (int i = 0; i < branch.N; i++)
                    {
                        bkx[i + branch.varOffset] = mosek.boundkey.fr;
                        blx[i + branch.varOffset] = 0;
                        bux[i + branch.varOffset] = 0;
                    }
                    //kink angle parameter
                    for (int i = 0; i < branch.tuples.Count(); i++)
                    {
                        bkx[branch.N + i + branch.varOffset] = mosek.boundkey.lo;
                        blx[branch.N + i + branch.varOffset] = 0.0;
                        bux[branch.N + i + branch.varOffset] = 0;
                    }
                }
                else if (branch.branchType == branch.type.open)
                {
                    for (int i = 0; i < branch.N; i++)
                    {
                        bkx[i + branch.varOffset] = mosek.boundkey.fr;
                        blx[i + branch.varOffset] = 0;
                        bux[i + branch.varOffset] = 0;
                    }
                    //kink angle parameter
                    for (int i = 0; i < branch.tuples.Count(); i++)
                    {
                        if (branch.range.rangeType == range.type.lo)
                        {
                            bkx[branch.N + i + branch.varOffset] = mosek.boundkey.lo;
                            blx[branch.N + i + branch.varOffset] = branch.range.lb;
                            bux[branch.N + i + branch.varOffset] = 0;
                        }
                        else if (branch.range.rangeType == range.type.up)
                        {
                            bkx[branch.N + i + branch.varOffset] = mosek.boundkey.up;
                            blx[branch.N + i + branch.varOffset] = 0;
                            bux[branch.N + i + branch.varOffset] = branch.range.ub;
                        }
                        else
                        {
                            bkx[branch.N + i + branch.varOffset] = mosek.boundkey.ra;
                            blx[branch.N + i + branch.varOffset] = branch.range.lb;
                            bux[branch.N + i + branch.varOffset] = branch.range.ub;
                        }
                        //bkx[branch.N + i + branch.varOffset] = mosek.boundkey.ra;
                        //blx[branch.N + i + branch.varOffset] = 0;
                        //bux[branch.N + i + branch.varOffset] = 0;
                    }
                }
                else if (branch.branchType == branch.type.kink)
                {
                    for (int i = 0; i < branch.N; i++)
                    {
                        bkx[i + branch.varOffset] = mosek.boundkey.fr;
                        blx[i + branch.varOffset] = -infinity;
                        bux[i + branch.varOffset] = infinity;
                    }
                    //kink angle parameter
                    for (int i = 0; i < branch.tuples.Count(); i++)
                    {
                        if (branch.range.rangeType == range.type.lo)
                        {
                            bkx[branch.N + i + branch.varOffset] = mosek.boundkey.lo;
                            blx[branch.N + i + branch.varOffset] = branch.range.lb;
                            bux[branch.N + i + branch.varOffset] = 0;
                        }
                        else if(branch.range.rangeType == range.type.up)
                        {
                            bkx[branch.N + i + branch.varOffset] = mosek.boundkey.up;
                            blx[branch.N + i + branch.varOffset] = 0;
                            bux[branch.N + i + branch.varOffset] = branch.range.ub;
                        }
                        else
                        {
                            bkx[branch.N + i + branch.varOffset] = mosek.boundkey.ra;
                            blx[branch.N + i + branch.varOffset] = branch.range.lb;
                            bux[branch.N + i + branch.varOffset] = branch.range.ub;
                        }
                    }
                }
                else//free
                {
                    for (int i = 0; i < branch.N; i++)
                    {
                        bkx[i + branch.varOffset] = mosek.boundkey.fr;
                        blx[i + branch.varOffset] = -infinity;
                        bux[i + branch.varOffset] = infinity;
                    }
                    //kink angle parameter
                    for (int i = 0; i < branch.tuples.Count(); i++)
                    {
                        bkx[branch.N + i + branch.varOffset] = mosek.boundkey.fr;
                        blx[branch.N + i + branch.varOffset] = -infinity;
                        bux[branch.N + i + branch.varOffset] = infinity;
                    }
                }
            }
            foreach (var slice in _listSlice.Values)
            {
                if (slice.sliceType == slice.type.fx)
                {
                    //add something!
                    bkx[slice.varOffset] = mosek.boundkey.fx;
                    blx[slice.varOffset] = slice.a;
                    bux[slice.varOffset] = slice.a;
                    bkx[slice.varOffset + 1] = mosek.boundkey.fx;
                    blx[slice.varOffset + 1] = slice.b;
                    bux[slice.varOffset + 1] = slice.b;
                    bkx[slice.varOffset + 2] = mosek.boundkey.fx;
                    blx[slice.varOffset + 2] = slice.d;
                    bux[slice.varOffset + 2] = slice.d;
                }
                else
                {
                    bkx[slice.varOffset] = mosek.boundkey.fr;
                    blx[slice.varOffset] = -infinity;
                    bux[slice.varOffset] = infinity;
                    bkx[slice.varOffset + 1] = mosek.boundkey.fr;
                    blx[slice.varOffset + 1] = -infinity;
                    bux[slice.varOffset + 1] = infinity;
                    bkx[slice.varOffset + 2] = mosek.boundkey.fr;
                    blx[slice.varOffset + 2] = -infinity;
                    bux[slice.varOffset + 2] = infinity;
                }
            }
            if (obj)
            {
                bkx[numvar - 1] = mosek.boundkey.fx;
                blx[numvar - 1] = allow;
                bux[numvar - 1] = allow;

                //bkx[numvar - 1] = mosek.boundkey.fr;
                //blx[numvar - 1] = -infinity;
                //bux[numvar - 1] = infinity;
            }

            // Make mosek environment.
            using (mosek.Env env = new mosek.Env())
            {
                // Create a task object.
                using (mosek.Task task = new mosek.Task(env, 0, 0))
                {
                    // Directs the log task stream to the user specified
                    // method msgclass.streamCB
                    task.set_Stream(mosek.streamtype.log, new msgclass(""));

                    /* Append 'numcon' empty constraints.
                       The constraints will initially have no bounds. */
                    task.appendcons(numcon);

                    /* Append 'numvar' variables.
                       The variables will initially be fixed at zero (x=0). */
                    task.appendvars(numvar);

                    for (int j = 0; j < numvar; ++j)
                    {
                        task.putvarbound(j, bkx[j], blx[j], bux[j]);
                    }
                    double root2 = Math.Sqrt(2);
                    foreach (var leaf in listLeaf)
                    {

                        double[] grad = new double[leaf.tuples[0].nNode];
                        double[] grad0 = new double[leaf.tuples[0].nNode];
                        double[] grad1i = new double[leaf.tuples[0].nNode];
                        double[] grad1j = new double[leaf.tuples[0].nNode];
                        //define H11,H12,H22
                        for (int i = 0; i < leaf.r; i++)
                        {
                            int N11 = i * 3; //condition number
                            int N22 = i * 3 + 1;
                            int N12 = i * 3 + 2;
                            int target = i * 3 + (leaf.nU * leaf.nV) + leaf.varOffset;   //variable number
                            task.putaij(N11+leaf.conOffset, target, -1);
                            task.putconbound(N11 + leaf.conOffset, mosek.boundkey.fx, 0, 0);
                            task.putaij(N22 + leaf.conOffset, target + 1, -1);
                            task.putconbound(N22 + leaf.conOffset, mosek.boundkey.fx, 0, 0);
                            task.putaij(N12 + leaf.conOffset, target + 2, -1);
                            task.putconbound(N12 + leaf.conOffset, mosek.boundkey.fx, 0, 0);
                            //N11
                            leaf.tuples[i].d2[0, 0].CopyTo(grad, 0);
                            leaf.tuples[i].d0.CopyTo(grad0, 0);
                            leaf.tuples[i].d1[0].CopyTo(grad1i, 0);
                            leaf.tuples[i].d1[0].CopyTo(grad1j, 0);
                            for (int k = 0; k < leaf.tuples[i].nNode; k++)
                            {
                                for (int j = 0; j < leaf.tuples[i].elemDim; j++)
                                {
                                    grad[k] -= leaf.tuples[i].Gammaijk[0, 0, j] * leaf.tuples[i].d1[j][k];
                                }
                                double val = 0;
                                val += grad[k];
                                task.putaij(N11 + leaf.conOffset, leaf.tuples[i].internalIndex[k] + leaf.varOffset, -val / root2);
                            }
                            //N22
                            leaf.tuples[i].d2[1, 1].CopyTo(grad, 0);
                            leaf.tuples[i].d0.CopyTo(grad0, 0);
                            leaf.tuples[i].d1[1].CopyTo(grad1i, 0);
                            leaf.tuples[i].d1[1].CopyTo(grad1j, 0);
                            for (int k = 0; k < leaf.tuples[i].nNode; k++)
                            {
                                for (int j = 0; j < leaf.tuples[i].elemDim; j++)
                                {
                                    grad[k] -= leaf.tuples[i].Gammaijk[1, 1, j] * leaf.tuples[i].d1[j][k];
                                }
                                double val = 0;
                                val += grad[k];
                                task.putaij(N22 + leaf.conOffset, leaf.tuples[i].internalIndex[k] + leaf.varOffset, -val / root2);
                            }
                            //N12
                            leaf.tuples[i].d2[0, 1].CopyTo(grad, 0);
                            leaf.tuples[i].d0.CopyTo(grad0, 0);
                            leaf.tuples[i].d1[0].CopyTo(grad1i, 0);
                            leaf.tuples[i].d1[1].CopyTo(grad1j, 0);
                            for (int k = 0; k < leaf.tuples[i].nNode; k++)
                            {
                                for (int j = 0; j < leaf.tuples[i].elemDim; j++)
                                {
                                    grad[k] -= leaf.tuples[i].Gammaijk[0, 1, j] * leaf.tuples[i].d1[j][k];
                                }
                                double val = 0;
                                val += grad[k];
                                task.putaij(N12 + leaf.conOffset, leaf.tuples[i].internalIndex[k] + leaf.varOffset, -val);
                            }
                        }
                        // mean curvature will be added here
                        //
                        //
                        for (int i = 0; i < leaf.r; i++)
                        {
                            int target = i * 3 + (leaf.nU * leaf.nV) + leaf.varOffset;   //variable number
                            int target2 = i + leaf.r*3+(leaf.nU * leaf.nV) + leaf.varOffset;   //variable number

                            int NH= leaf.r*3+i; //condition number
                            task.putaij(NH + leaf.conOffset, target, 1);
                            task.putaij(NH + leaf.conOffset, target + 1, 1);
                            task.putaij(NH + leaf.conOffset, target2, -1);
                            task.putconbound(NH+leaf.conOffset, mosek.boundkey.fx, 0, 0);

                        }

                        //if (leaf.leafType == leaf.type.convex)
                        for (int i = 0; i < leaf.r; i++)
                        {
                            int N11 = i * 3 + (leaf.nU * leaf.nV); //variable number
                            int N22 = i * 3 + 1 + (leaf.nU * leaf.nV);
                            int N12 = i * 3 + 2 + (leaf.nU * leaf.nV);

                            csub[0] = N11 + leaf.varOffset;
                            csub[1] = N22 + leaf.varOffset;
                            csub[2] = N12 + leaf.varOffset;
                            task.appendcone(mosek.conetype.rquad,
                                            0.0, // For future use only, can be set to 0.0
                                            csub);
                            /*if (obj2)
                            {
                                task.putcj(N11, leaf.tuples[i].Gij[0, 0]);
                                task.putcj(N22, leaf.tuples[i].Gij[1, 1]);
                                task.putcj(N12, 2*leaf.tuples[i].Gij[0, 1]);
                            }*/
                        }
                        if (obj)
                        {
                            double[] grad00 = new double[leaf.tuples[0].nNode];
                            for (int i = 0; i < leaf.r; i++)
                            {
                                leaf.tuples[i].d0.CopyTo(grad00, 0);
                                for (int k = 0; k < leaf.tuples[i].nNode; k++)
                                {
                                    task.putaij(leaf.conOffset + leaf.r * 4 + i, leaf.varOffset + leaf.tuples[i].internalIndex[k], grad00[k]);
                                }
                                task.putaij(leaf.conOffset + leaf.r * 4 + i, leaf.varOffset + leaf.nU*leaf.nV+leaf.r*4+i,-1);
                                task.putconbound(leaf.conOffset + leaf.r * 4 + i, mosek.boundkey.fx, 0, 0);
                            }
                            for (int i = 0; i < leaf.tuples.Count(); i++)
                            {
                                task.putaij(leaf.conOffset + leaf.r * 5 + i, leaf.varOffset + leaf.nU * leaf.nV + leaf.r * 4 + i, 1);
                                task.putaij(leaf.conOffset + leaf.r * 5 + i, leaf.varOffset + leaf.nU * leaf.nV + leaf.r * 5 + i, -1);
                                task.putaij(leaf.conOffset + leaf.r * 5 + i, leaf.varOffset + leaf.nU * leaf.nV + leaf.r * 6 + i, -1);
                                task.putconbound(leaf.conOffset + leaf.r * 5 + i, mosek.boundkey.fx, 0, 0);
                            }
                        }
                    }

                    if (obj)
                    {
                        List<int> dsub=new List<int>();
                        dsub.Add(numvar-1);
                        foreach (var leaf in _listLeaf)
                        {
                            for (int i = 0; i < leaf.r; i++)
                            {
                                dsub.Add(leaf.varOffset + leaf.nU * leaf.nV + leaf.r * 6 + i);
                            }
                        }
                        task.appendcone(mosek.conetype.quad, 0.0, dsub.ToArray());
                    }
                    foreach (var branch in _listBranch)
                    {
                        if (branch.branchType == branch.type.kink)
                        {
                            tieBranchD1(branch, branch.left, task, 2, 0);
                            tieBranchD1(branch, branch.right, task, 2, 1);
                            defineKinkAngle2(branch,branch.left,branch.right,task, branch.conOffset + branch.N*2, branch.varOffset + branch.N);
                            /*if (branch.obj)
                            {
                                for (int i = 0; i < branch.tuples.Count(); i++)
                                {
                                    task.putcj(branch.N + i + branch.varOffset, 1);
                                }
                            }*/
                        }
                        else if (branch.branchType == branch.type.reinforce || branch.branchType == branch.type.open)
                        {
                            int iA = _listSlice[branch.sliceKey].varOffset;
                            int iB = _listSlice[branch.sliceKey].varOffset + 1;
                            int iD = _listSlice[branch.sliceKey].varOffset + 2;
                            //height parameter
                            for (int i = 0; i < branch.N; i++)
                            {
                                double x = branch.crv.Points[i].Location.X;
                                double y = branch.crv.Points[i].Location.Y;
                                task.putconbound(branch.conOffset + branch.N + branch.tuples.Count() + i, mosek.boundkey.fx, 0, 0);
                                task.putaij(branch.conOffset + branch.N + branch.tuples.Count() + i, branch.varOffset + i, 1);//z
                                task.putaij(branch.conOffset + branch.N + branch.tuples.Count() + i, iA, x);//ax
                                task.putaij(branch.conOffset + branch.N + branch.tuples.Count() + i, iB, y);//by
                                task.putaij(branch.conOffset + branch.N + branch.tuples.Count() + i, iD, 1);//d
                            }
                            tieBranchD1(branch, branch.target, task, 1, 0);
                            defineKinkAngleC(branch, branch.target, task, branch.conOffset + branch.N, branch.varOffset + branch.N);
                        }
                        else
                        {
                            tieBranchD1(branch, branch.target, task, 1, 0);
                            defineKinkAngle(branch,branch.target, task, branch.conOffset + branch.N, branch.varOffset + branch.N);
                        }
                    }
                    //task.putcj(numvar - 1, 1);
                    task.putintparam(mosek.iparam.intpnt_max_iterations, 200000000);//20000000
                    task.putintparam(mosek.iparam.intpnt_solve_form, mosek.solveform.dual);
                    task.putobjsense(mosek.objsense.minimize);
                    //task.writedata("c:/out/mosek_task_dump.opf");

                    task.optimize();
                    // Print a summary containing information
                    //   about the solution for debugging purposes
                    task.solutionsummary(mosek.streamtype.msg);

                    mosek.solsta solsta;
                    /* Get status information about the solution */
                    task.getsolsta(mosek.soltype.itr, out solsta);

                    double[] xx = new double[numvar];

                    task.getxx(mosek.soltype.itr, // Basic solution.
                                    xx);

                    switch (solsta)
                    {
                        case mosek.solsta.optimal:
                            System.Windows.Forms.MessageBox.Show("Optimal primal solution\n");
                            break;
                        case mosek.solsta.near_optimal:
                            System.Windows.Forms.MessageBox.Show("Near Optimal primal solution\n");
                            break;
                        case mosek.solsta.dual_infeas_cer:
                        case mosek.solsta.prim_infeas_cer:
                        case mosek.solsta.near_dual_infeas_cer:
                        case mosek.solsta.near_prim_infeas_cer:
                            Console.WriteLine("Primal or dual infeasibility.\n");
                            break;
                        case mosek.solsta.unknown:
                            System.Windows.Forms.MessageBox.Show("Unknown solution status\n");
                            break;
                        default:
                            System.Windows.Forms.MessageBox.Show("Other solution status\n");
                            break;

                    }
                    //store airy potential
                    System.Windows.Forms.MessageBox.Show(string.Format("error={0}", xx[numvar - 1]));
                    foreach (var leaf in listLeaf)
                    {
                        double[] x = new double[leaf.nU * leaf.nV];
                        for (int j = 0; j < leaf.nV; j++)
                        {
                            for (int i = 0; i < leaf.nU; i++)
                            {
                                x[i + j * leaf.nU] = xx[i + j * leaf.nU + leaf.varOffset];
                            }
                        }
                        leaf.myMasonry.setupAiryPotentialFromList(x);
                    }
                    foreach (var leaf in listLeaf)
                    {
                        foreach (var tup in leaf.tuples)
                        {
                            leaf.myMasonry.elemList[tup.index].computeStressFunction(tup);
                        }
                    }
                    foreach (var branch in _listBranch)
                    {
                        double[] x = new double[branch.N];
                        for (int i = 0; i < branch.N; i++)
                        {
                            x[i] = xx[i + branch.varOffset];
                        }
                        branch.myArch.setupAiryPotentialFromList(x);
                    }
                    foreach (var slice in _listSlice.Values)
                    {
                        slice.a = xx[slice.varOffset];
                        slice.b = xx[slice.varOffset + 1];
                        slice.d = xx[slice.varOffset + 2];
                        double norm = Math.Sqrt(slice.a * slice.a + slice.b * slice.b + 1);
                        var pl = new Rhino.Geometry.Plane(slice.a, slice.b, 1d, slice.d / norm);
                        slice.update(pl);
                    }
                    foreach (var branch in listBranch)
                    {
                        foreach (var tup in branch.tuples)
                        {
                            if (branch.branchType == branch.type.kink)
                            {
                                branch.left.myMasonry.elemList[tup.left.index].computeTangent(tup.left);
                                branch.right.myMasonry.elemList[tup.right.index].computeTangent(tup.right);
                            }
                            else if (branch.branchType == branch.type.fix)
                            {
                                branch.target.myMasonry.elemList[tup.target.index].computeTangent(tup.target);
                            }
                            else
                            {

                                branch.target.myMasonry.elemList[tup.target.index].computeTangent(tup.target);
                                var vars = branch.slice.pl.GetPlaneEquation();
                                branch.target.myMasonry.elemList[tup.target.index].computeTangent(tup.target, vars[0], vars[1], vars[2], vars[3]); //valDc
                            }
                        }
                    }
                    foreach (var leaf in _listLeaf)
                    {
                        for (int i = 0; i < leaf.r; i++)
                        {
                            int target = i + leaf.r*3+(leaf.nU * leaf.nV) + leaf.varOffset;
                            leaf.tuples[i].NH = xx[target];
                        }
                    }
                    foreach (var branch in _listBranch)
                    {
                        branch.airyCrv = branch.crv.Duplicate() as NurbsCurve;
                        for (int j = 0; j < branch.N; j++)
                        {
                            var P = branch.crv.Points[j];
                            branch.airyCrv.Points.SetPoint(j, new Point3d(P.Location.X, P.Location.Y, xx[j + branch.varOffset]));
                        }
                        for (int i = 0; i < branch.tuples.Count(); i++)
                        {
                            //branch.tuples[i].z = branch.airyCrv.PointAt(branch.tuples[i].t).Z;
                            //int D = i + branch.N;
                            if (branch.branchType == branch.type.open)
                            {
                                branch.tuples[i].H[0, 0] = branch.tuples[i].target.valD - branch.tuples[i].target.valDc;
                            }
                            else if (branch.branchType == branch.type.reinforce)
                            {
                                branch.tuples[i].H[0, 0] = branch.tuples[i].target.valD - branch.tuples[i].target.valDc;
                            }
                            else if (branch.branchType == branch.type.fix)
                            {
                                branch.tuples[i].H[0, 0] = 0;
                            }
                            else
                            {
                                //afterwards, check why these two values do not match.
                                //branch.tuples[i].H[0, 0] = branch.tuples[i].left.valD + branch.tuples[i].right.valD;
                                branch.tuples[i].H[0, 0] = xx[branch.N + i + branch.varOffset];
                            }
                        }
                    }
                    foreach (var range in _listRangeLeaf.Values)
                    {
                        double min = 10000d, max = -10000d;
                        foreach (var leaf in range.lL)
                        {
                            for (int i = 0; i < leaf.tuples.Count(); i++)
                            {
                                if (leaf.tuples[i].NH > max) max = leaf.tuples[i].NH;
                                if (leaf.tuples[i].NH < min) min = leaf.tuples[i].NH;
                            }
                        }
                        range.lastMin = min;
                        range.lastMax = max;
                        range.firstPathDone = true;
                    }
                    foreach (var range in _listRange.Values)
                    {
                        double min=10000d,max=-10000d;
                        foreach (var branch in range.lB)
                        {
                            for(int i=0;i<branch.tuples.Count();i++)
                            {
                                if (branch.tuples[i].H[0, 0] > max) max = branch.tuples[i].H[0, 0];
                                if (branch.tuples[i].H[0, 0] < min) min = branch.tuples[i].H[0, 0];
                            }
                        }
                        range.lastMin = min;
                        range.lastMax = max;
                        range.firstPathDone = true;
                    }
                    foreach (var range in _listRangeOpen.Values)
                    {
                        double min = 10000d, max = -10000d;
                        foreach (var branch in range.lB)
                        {
                            for (int i = 0; i < branch.tuples.Count(); i++)
                            {
                                if (branch.tuples[i].H[0, 0] > max) max = branch.tuples[i].H[0, 0];
                                if (branch.tuples[i].H[0, 0] < min) min = branch.tuples[i].H[0, 0];
                            }
                        }
                        range.lastMin = min;
                        range.lastMax = max;
                        range.firstPathDone = true;
                    }

                    foreach (var leaf in _listLeaf)
                    {
                        leaf.airySrf = leaf.srf.Duplicate() as NurbsSurface;
                        for (int j = 0; j < leaf.nV; j++)
                        {
                            for (int i = 0; i < leaf.nU; i++)
                            {
                                var P = leaf.srf.Points.GetControlPoint(i, j);
                                leaf.airySrf.Points.SetControlPoint(i, j, new ControlPoint(P.Location.X, P.Location.Y, xx[i + j * leaf.nU + leaf.varOffset]));
                            }
                        }
                    }
                }
            }
        }
        public void Optimize(Story story, PositionTable <double> position, PositionTable <int> segment)
        {
            int           count = -1;
            List <double> X     = new List <double>();

            int[,] index = new int[story.Characters.Count, story.FrameCount];
            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount; ++frame)
                {
                    index[i, frame] = -2;
                }
            }
            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount; ++frame)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        if (frame > 0 && story.SessionTable[i, frame - 1] != -1 && segment[i, frame] == segment[i, frame - 1])
                        {
                            index[i, frame] = count;
                        }
                        else
                        {
                            index[i, frame] = ++count;
                            X.Add(position[i, frame]);
                        }
                    }
                }
            }

            Dictionary <Tuple <int, int>, double> Q = new Dictionary <Tuple <int, int>, double>();

            for (int i = 0; i < X.Count; ++i)
            {
                Q.Add(new Tuple <int, int>(i, i), 1);
            }

            //int[,] Q = new int[X.Count, X.Count];
            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount - 1; ++frame)
                {
                    int left  = frame;
                    int right = frame + 1;
                    if (story.SessionTable[i, left] != -1 && story.SessionTable[i, right] != -1 && segment[i, left] != segment[i, right])
                    {
                        if (!Q.ContainsKey(new Tuple <int, int>(index[i, left], index[i, left])))
                        {
                            Q.Add(new Tuple <int, int>(index[i, left], index[i, left]), 0);
                        }
                        if (!Q.ContainsKey(new Tuple <int, int>(index[i, right], index[i, right])))
                        {
                            Q.Add(new Tuple <int, int>(index[i, right], index[i, right]), 0);
                        }
                        if (!Q.ContainsKey(new Tuple <int, int>(index[i, left], index[i, right])))
                        {
                            Q.Add(new Tuple <int, int>(index[i, left], index[i, right]), 0);
                        }
                        if (!Q.ContainsKey(new Tuple <int, int>(index[i, right], index[i, left])))
                        {
                            Q.Add(new Tuple <int, int>(index[i, right], index[i, left]), 0);
                        }
                        Q[new Tuple <int, int>(index[i, left], index[i, left])]   += 2;
                        Q[new Tuple <int, int>(index[i, right], index[i, right])] += 2;
                        Q[new Tuple <int, int>(index[i, left], index[i, right])]  -= 2;
                        Q[new Tuple <int, int>(index[i, right], index[i, left])]  -= 2;
                    }
                }
            }

            List <int>    li = new List <int>();
            List <int>    lj = new List <int>();
            List <double> lv = new List <double>();

            foreach (KeyValuePair <Tuple <int, int>, double> pair in Q)
            {
                if (pair.Key.Item1 >= pair.Key.Item2 && pair.Value != 0)
                {
                    li.Add(pair.Key.Item1);
                    lj.Add(pair.Key.Item2);
                    lv.Add((double)pair.Value);
                }
            }

            int[]    qsubi = li.ToArray();
            int[]    qsubj = lj.ToArray();
            double[] qval  = lv.ToArray();


            List <Tuple <int, int> > listInner = new List <Tuple <int, int> >();
            List <Tuple <int, int> > listOuter = new List <Tuple <int, int> >();

            for (int frame = 0; frame < story.FrameCount; ++frame)
            {
                List <Tuple <int, double> > l = new List <Tuple <int, double> >();
                for (int i = 0; i < story.Characters.Count; ++i)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        l.Add(new Tuple <int, double>(i, position[i, frame]));
                    }
                }
                l.Sort((a, b) => a.Item2.CompareTo(b.Item2));
                for (int k = 0; k < l.Count - 1; ++k)
                {
                    int x = l[k].Item1;
                    int y = l[k + 1].Item1;
                    if (story.SessionTable[x, frame] == story.SessionTable[y, frame])
                    {
                        if (!listInner.Contains(new Tuple <int, int>(index[x, frame], index[y, frame])))
                        {
                            listInner.Add(new Tuple <int, int>(index[x, frame], index[y, frame]));
                        }
                    }
                    else
                    {
                        if (!listOuter.Contains(new Tuple <int, int>(index[x, frame], index[y, frame])))
                        {
                            listOuter.Add(new Tuple <int, int>(index[x, frame], index[y, frame]));
                        }
                    }
                }
            }

            Debug.Assert(!ExistingCircle(listInner, X.Count));
            Debug.Assert(!ExistingCircle(listOuter, X.Count));

            foreach (Tuple <int, int> tuple in listInner)
            {
                Debug.Write(tuple.Item1.ToString() + "->" + tuple.Item2.ToString() + ", ");
            }

            const double infinity      = 0;
            int          NumConstraint = listInner.Count + listOuter.Count;
            int          NumVariable   = X.Count;


            double[]         blx = new double[NumVariable];
            double[]         bux = new double[NumVariable];
            mosek.boundkey[] bkx = new mosek.boundkey[NumVariable];

            for (int i = 0; i < NumVariable; ++i)
            {
                bkx[i] = mosek.boundkey.ra;
                blx[i] = -12000;
                bux[i] = 12000;
            }
            bkx[0] = mosek.boundkey.fx;
            bkx[0] = 0;
            bkx[0] = 0;


            int[][]    asub = new int[NumVariable][];
            double[][] aval = new double[NumVariable][];


            List <int>[]    asubList = new List <int> [NumVariable];
            List <double>[] avalList = new List <double> [NumVariable];
            for (int i = 0; i < NumVariable; ++i)
            {
                asubList[i] = new List <int>();
                avalList[i] = new List <double>();
            }
            for (int i = 0; i < listInner.Count; ++i)
            {
                Tuple <int, int> pair = listInner[i];
                int x = pair.Item1;
                int y = pair.Item2;

                asubList[x].Add(i);
                avalList[x].Add(-1);

                asubList[y].Add(i);
                avalList[y].Add(1);
            }
            for (int i = 0; i < listOuter.Count; ++i)
            {
                int j = i + listInner.Count;
                Tuple <int, int> pair = listOuter[i];
                int x = pair.Item1;
                int y = pair.Item2;
                asubList[x].Add(j);
                avalList[x].Add(-1);

                asubList[y].Add(j);
                avalList[y].Add(1);
            }
            for (int i = 0; i < NumVariable; ++i)
            {
                asub[i] = asubList[i].ToArray();
                aval[i] = avalList[i].ToArray();
            }
            mosek.boundkey[] bkc = new mosek.boundkey[NumConstraint];
            double[]         blc = new double[NumConstraint];
            double[]         buc = new double[NumConstraint];
            for (int i = 0; i < listInner.Count; ++i)
            {
                bkc[i] = mosek.boundkey.fx;
                //blc[i] = 28;
                //buc[i] = 28;
                blc[i] = _app.Status.Config.Style.DefaultInnerGap;
                buc[i] = _app.Status.Config.Style.DefaultInnerGap;
            }
            for (int i = listInner.Count; i < listInner.Count + listOuter.Count; ++i)
            {
                bkc[i] = mosek.boundkey.lo;
                //blc[i] = 84;
                blc[i] = _app.Status.Config.Style.OuterGap;
                buc[i] = 1000;
            }

            mosek.Task task  = null;
            mosek.Env  env   = null;
            double[]   xx    = new double[NumVariable];
            DateTime   start = DateTime.Now;

            try
            {
                env = new mosek.Env();
                env.set_Stream(mosek.streamtype.log, new msgclass(""));
                env.init();

                task = new mosek.Task(env, 0, 0);
                task.set_Stream(mosek.streamtype.log, new msgclass(""));
                task.putmaxnumvar(NumVariable);
                task.putmaxnumcon(NumConstraint);

                //task.putdouparam(mosek.dparam.intpnt_nl_tol_pfeas, 1.0e-1);
                //task.putdouparam(mosek.dparam.intpnt_tol_dfeas, 1.0e-1);
                //task.putdouparam(mosek.dparam.intpnt_nl_tol_rel_gap, 1.0e-1);
                //task.putdouparam(mosek.dparam.intpnt_co_tol_infeas, 1.0e-13);
                //task.putdouparam(mosek.dparam.intpnt_nl_tol_mu_red, 1.0e-13);


                task.append(mosek.accmode.con, NumConstraint);
                task.append(mosek.accmode.var, NumVariable);

                task.putcfix(0.0);

                for (int j = 0; j < NumVariable; ++j)
                {
                    task.putcj(j, 0);
                    task.putbound(mosek.accmode.var, j, bkx[j], blx[j], bux[j]);

                    task.putavec(mosek.accmode.var, j, asub[j], aval[j]);
                }

                for (int i = 0; i < NumConstraint; ++i)
                {
                    task.putbound(mosek.accmode.con, i, bkc[i], blc[i], buc[i]);
                }

                task.putobjsense(mosek.objsense.minimize);
                task.putqobj(qsubi, qsubj, qval);

                task.optimize();
                task.solutionsummary(mosek.streamtype.msg);

                mosek.solsta solsta;
                mosek.prosta prosta;

                task.getsolutionstatus(mosek.soltype.itr,
                                       out prosta,
                                       out solsta);
                task.getsolutionslice(mosek.soltype.itr,
                                      mosek.solitem.xx,
                                      0,
                                      NumVariable,
                                      xx);

                switch (solsta)
                {
                case mosek.solsta.optimal:
                case mosek.solsta.near_optimal:
                    Console.WriteLine("Optimal primal solution\n");
                    //for (int j = 0; j < NumVariable; ++j)
                    //    Console.WriteLine("x[{0}]:", xx[j]);
                    break;

                case mosek.solsta.dual_infeas_cer:
                case mosek.solsta.prim_infeas_cer:
                case mosek.solsta.near_dual_infeas_cer:
                case mosek.solsta.near_prim_infeas_cer:
                    Console.WriteLine("Primal or dual infeasibility.\n");
                    break;

                case mosek.solsta.unknown:
                    Console.WriteLine("Unknown solution status.\n");
                    break;

                default:
                    Console.WriteLine("Other solution status");
                    break;
                }
            }
            catch (mosek.Exception e)
            {
                Console.WriteLine(e.Code);
                Console.WriteLine(e);
            }
            finally
            {
                if (task != null)
                {
                    task.Dispose();
                }
                if (env != null)
                {
                    env.Dispose();
                }
            }

            Console.WriteLine("///{0}", DateTime.Now - start);

            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount; ++frame)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        position[i, frame] = xx[index[i, frame]];
                    }
                }
            }
        }
Exemple #6
0
    public static void Main ()
    {
      const double
        infinity = 0;            
    
      mosek.boundkey[] bkc = new mosek.boundkey[]{
      mosek.boundkey.up,mosek.boundkey.up,
      mosek.boundkey.up,mosek.boundkey.fx,
      mosek.boundkey.fx,mosek.boundkey.fx,
      mosek.boundkey.fx
      };

      mosek.boundkey[] bkx = new mosek.boundkey[]{
      mosek.boundkey.lo,mosek.boundkey.lo,
      mosek.boundkey.lo,mosek.boundkey.lo,
      mosek.boundkey.lo,mosek.boundkey.lo,
      mosek.boundkey.lo};

      int[] ptrb= new int[]{0,2,4,6,8,10,12};
      int[] ptre= new int[]{2,4,6,8,10,12,14};
      int[] sub = new int[]{0,3,0,4,1,5,1,6,2,3,2,5,2,6};
      double[] blc = new double[]{
      -infinity,-infinity,
      -infinity,800,100,500,500};

      double[] buc = new double[]{400,1200,1000,800,100,500,500};
      double[] c   = new double[]{1.0,2.0,5.0,2.0,1.0,2.0,1.0};
      double[] blx = new double[]{0.0,0.0,0.0,0.0,0.0,0.0,0.0};
      double[] bux = new double[]{infinity,
                                  infinity,
                                  infinity,
                                  infinity,
                                  infinity,
                                  infinity,
                                  infinity};

      double[] val = new double[]{1.0,1.0,1.0,1.0,1.0,1.0,1.0,
                                  1.0,1.0,1.0,1.0,1.0,1.0,1.0};

      int numcon = 7;  /* Number of constraints.             */
      int numvar = 7;  /* Number of variables.               */
      try
      {
        using (mosek.Env env = new mosek.Env())
        { 
          using (mosek.Task task = new mosek.Task(env))
          {
            // Directs the log task stream to the user specified
            // method task_msg_obj.streamCB
            task.set_Stream(mosek.streamtype.log, new msgclass ("[task]"));
        
            task.inputdata(numcon,numvar,
                           c,
                           0.0,
                           ptrb,
                           ptre,
                           sub,
                           val,
                           bkc,
                           blc,
                           buc,
                           bkx,
                           blx,
                           bux);
              
            /* A maximization problem */ 
            task.putobjsense(mosek.objsense.minimize);

            try
              {
                task.optimize();
              }
            catch (mosek.Warning w)
              {
                Console.WriteLine("Mosek warning:");
                Console.WriteLine (w.Code);
                Console.WriteLine (w);
              }
              

            /* Analyze upper bound on c1 and the equality constraint on c4 */ 
            int[] subi  = new int []{0,3};         
            mosek.mark[] marki = new mosek.mark[]{mosek.mark.up,
                                                          mosek.mark.up};

            /* Analyze lower bound on the variables x12 and x31 */ 
            int[] subj  = new int []{1,4};
            mosek.mark[] markj = new mosek.mark[] {mosek.mark.lo,
                                                           mosek.mark.lo};
         
            double[] leftpricei  = new  double[2];
            double[] rightpricei = new  double[2];  
            double[] leftrangei  = new  double[2];
            double[] rightrangei = new  double[2];
            double[] leftpricej  = new  double[2];
            double[] rightpricej = new  double[2];
            double[] leftrangej  = new  double[2];
            double[] rightrangej = new  double[2];

          
            task.primalsensitivity( subi, 
                                    marki,  
                                    subj,
                                    markj, 
                                    leftpricei,   
                                    rightpricei,
                                    leftrangei, 
                                    rightrangei,
                                    leftpricej,   
                                    rightpricej,
                                    leftrangej, 
                                    rightrangej);

            Console.Write("Results from sensitivity analysis on bounds:\n");

            Console.Write("For constraints:\n");
            for (int i=0;i<2;++i)
              Console.Write(
              "leftprice = {0}, rightprice = {1},leftrange = {2}, rightrange ={3}\n",
               leftpricei[i], rightpricei[i], leftrangei[i], rightrangei[i]);
                  
            Console.Write("For variables:\n");
            for (int i=0;i<2;++i)
              Console.Write(
              "leftprice = {0}, rightprice = {1},leftrange = {2}, rightrange ={3}\n",
               leftpricej[i], rightpricej[i], leftrangej[i], rightrangej[i]);   
                      

            double[] leftprice  = new  double[2];
            double[] rightprice = new  double[2];
            double[] leftrange  = new  double[2];
            double[] rightrange = new  double[2];
            int[] subc = new int[]{2,5};
         
            task.dualsensitivity(  subc,
                                   leftprice,
                                   rightprice,
                                   leftrange,
                                   rightrange
                                   );

            Console.Write("Results from sensitivity analysis on objective coefficients:");
      
            for (int i=0;i<2;++i)
              Console.Write(
              "leftprice = {0}, rightprice = {1},leftrange = {2}, rightrange = {3}\n",
              leftprice[i], rightprice[i], leftrange[i], rightrange[i]);               
          }
        }
      }
      catch (mosek.Exception e)
        {
          Console.WriteLine (e.Code);
          Console.WriteLine (e);
          throw;
        }
    }
    public static void Main(string[] args)
    {
        mosek.Env
            env = null;
        mosek.Task
            task = null;
        int
            numvar = 0;

        try
        {
            env = new mosek.Env();
            env.init();
            task = new mosek.Task(env, 0, 0);
            {
                double[] c = new double[numvar];
                task.getc(c);
            }
            {
                double[]         upper_bound = new double[8];
                double[]         lower_bound = new double[8];
                mosek.boundkey[] bound_key   = new mosek.boundkey[8];
                task.getboundslice(mosek.accmode.con, 2, 10,
                                   bound_key, lower_bound, upper_bound);
            }
            {
                int[]            bound_index = { 1, 6, 3, 9 };
                mosek.boundkey[] bound_key   =
                { mosek.boundkey.fr,
                  mosek.boundkey.lo,
                  mosek.boundkey.up,
                  mosek.boundkey.fx };
                double[] lower_bound = { 0.0, -10.0, 0.0, 5.0 };
                double[] upper_bound = { 0.0, 0.0, 6.0, 5.0 };
                task.putboundlist(mosek.accmode.con, bound_index,
                                  bound_key, lower_bound, upper_bound);
            }
            {
                int[]    subi = { 1, 3, 5 };
                int[]    subj = { 2, 3, 4 };
                double[] cof  = { 1.1, 4.3, 0.2 };
                task.putaijlist(subi, subj, cof);
            }


            {
                int[]    rowsub = { 0, 1, 2, 3 };
                int[]    ptrb   = { 0, 3, 5, 7 };
                int[]    ptre   = { 3, 5, 7, 8 };
                int[]    sub    = { 0, 2, 3, 1, 4, 0, 3, 2 };
                double[] cof    = { 1.1, 1.3, 1.4, 2.2, 2.5, 3.1, 3.4, 4.4 };

                task.putaveclist(mosek.accmode.con,
                                 rowsub, ptrb, ptre,
                                 sub, cof);
            }
        }
        catch (mosek.ArrayLengthException e)
        {
            Console.WriteLine("Error: An array was too short");
            Console.WriteLine(e.ToString());
        }
        catch (mosek.Exception e)
        /* Catch both mosek.Error and mosek.Warning */
        {
            Console.WriteLine("An error or warning was encountered");
            Console.WriteLine(e.ToString());
        }

        if (task != null)
        {
            task.Dispose();
        }
        if (env != null)
        {
            env.Dispose();
        }
    }
Exemple #8
0
        public static void Main()
        {
            const int numcon = 1;
            const int numvar = 6;

            // Since the value infinity is never used, we define
            // 'infinity' symbolic purposes only
            double infinity = 0;

            mosek.boundkey[] bkx = new mosek.boundkey[numvar];
            double[]         blx = new double[numvar];
            double[]         bux = new double[numvar];

            double[] val = { 1.0, 1.0, -1.0 };
            int[]    sub = { 3, 4, 0 };

            double[] aval = { 1.0, 1.0, 0.5 };
            int[]    asub = { 0, 1, 2 };

            int i;

            double[] xx = new double[numvar];

            // Make mosek environment.
            using (mosek.Env env = new mosek.Env())
            {
                // Create a task object.
                using (mosek.Task task = new mosek.Task(env, 0, 0))
                {
                    // Directs the log task stream to the user specified
                    // method msgclass.streamCB
                    task.set_Stream(mosek.streamtype.log, new msgclass(""));

                    /* Append 'numcon' empty constraints.
                     * The constraints will initially have no bounds. */
                    task.appendcons(numcon);

                    /* Append 'numvar' variables.
                     * The variables will initially be fixed at zero (x=0). */
                    task.appendvars(numvar);

                    /* Set up the linear part of the problem */
                    task.putclist(sub, val);
                    task.putarow(0, asub, aval);
                    task.putconbound(0, mosek.boundkey.fx, 2.0, 2.0);
                    for (i = 0; i < 5; i++)
                    {
                        bkx[i] = mosek.boundkey.fr;
                        blx[i] = -infinity;
                        bux[i] = infinity;
                    }
                    bkx[5] = mosek.boundkey.fx;
                    blx[5] = bux[5] = 1.0;
                    task.putvarboundslice(0, numvar, bkx, blx, bux);

                    /* Add a conic constraint */
                    task.appendcone(mosek.conetype.ppow, 0.2, new int[3] {
                        0, 1, 3
                    });
                    task.appendcone(mosek.conetype.ppow, 0.4, new int[3] {
                        2, 5, 4
                    });

                    task.putobjsense(mosek.objsense.maximize);
                    task.optimize();

                    // Print a summary containing information
                    // about the solution for debugging purposes
                    task.solutionsummary(mosek.streamtype.msg);

                    mosek.solsta solsta;
                    /* Get status information about the solution */
                    task.getsolsta(mosek.soltype.itr, out solsta);

                    task.getxx(mosek.soltype.itr, // Basic solution.
                               xx);

                    switch (solsta)
                    {
                    case mosek.solsta.optimal:
                        Console.WriteLine("Optimal primal solution\n");
                        for (int j = 0; j < 3; ++j)
                        {
                            Console.WriteLine("x[{0}]: {1}", j, xx[j]);
                        }
                        break;

                    case mosek.solsta.dual_infeas_cer:
                    case mosek.solsta.prim_infeas_cer:
                        Console.WriteLine("Primal or dual infeasibility.\n");
                        break;

                    case mosek.solsta.unknown:
                        Console.WriteLine("Unknown solution status.\n");
                        break;

                    default:
                        Console.WriteLine("Other solution status");
                        break;
                    }
                }
            }
        }
Exemple #9
0
            public static void Main(string[] args)
            {
                using (mosek.Env env = new mosek.Env())
                {
                    using (mosek.Task task = new mosek.Task(env, 0, 0))
                    {
                        task.set_Stream(mosek.streamtype.log, new msgclass());
                        int numvar = 6;
                        int numcon = 5;


                        mosek.boundkey[]
                        bkc = new mosek.boundkey[] { mosek.boundkey.up,
                                                     mosek.boundkey.fx,
                                                     mosek.boundkey.fx,
                                                     mosek.boundkey.fx,
                                                     mosek.boundkey.fx };
                        double[]
                        blc = new double[] { 0.0, 0.0, 0.0, 1.3862944, 0.0 },
                        buc = new double[] { 1.0, 0.0, 0.0, 1.3862944, 0.0 };

                        mosek.boundkey[]
                        bkx = new mosek.boundkey[] { mosek.boundkey.fr,
                                                     mosek.boundkey.fr,
                                                     mosek.boundkey.fr,
                                                     mosek.boundkey.fr,
                                                     mosek.boundkey.fr,
                                                     mosek.boundkey.fr };
                        double[]
                        blx = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },
                        bux = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };

                        long[]
                        aptrb = new long[] { 0, 0, 3, 6, 8 },
                        aptre = new long[] { 0, 3, 6, 8, 10 };
                        int[]
                        asubi = new int[] { 0, 1, 2, 3, 4 },
                        asubj = new int[] { 0, 1, 2,
                                            0, 1, 3,
                                            0, 4,
                                            1, 5 };
                        double[]
                        aval = new double[] { 1.0, 1.0, -1.0,
                                              -1.0, -1.0, -1.0,
                                              0.5, -1.0,
                                              1.0, -1.0 };

                        task.appendvars(numvar);
                        task.appendcons(numcon);

                        task.putobjsense(mosek.objsense.minimize);

                        task.putvarboundslice(0, numvar, bkx, blx, bux);
                        task.putconboundslice(0, numcon, bkc, blc, buc);

                        task.putarowlist(asubi, aptrb, aptre, asubj, aval);

                        mosek.scopr[]
                        opro = new mosek.scopr[] { mosek.scopr.exp,
                                                   mosek.scopr.exp };
                        int[]
                        oprjo = new int[] { 2, 3 };
                        double[]
                        oprfo = new double[] { 1.0, 1.0 },
                        oprgo = new double[] { 1.0, 1.0 },
                        oprho = new double[] { 0.0, 0.0 };

                        mosek.scopr[]
                        oprc = new mosek.scopr[] { mosek.scopr.exp,
                                                   mosek.scopr.exp };
                        int[]
                        opric = new int[] { 0, 0 },
                        oprjc = new int[] { 4, 5 };
                        double[]
                        oprfc = new double[] { 1.0, 1.0 },
                        oprgc = new double[] { 1.0, 1.0 },
                        oprhc = new double[] { 0.0, 0.0 };

                        task.putSCeval(opro, oprjo, oprfo, oprgo, oprho,
                                       oprc, opric, oprjc, oprfc, oprgc, oprhc);

                        task.optimize();
                        task.solutionsummary(mosek.streamtype.msg);
                        double[] res = new double[numvar];
                        task.getsolutionslice(mosek.soltype.itr,
                                              mosek.solitem.xx,
                                              0, numvar,
                                              res);

                        System.Console.Write("Solution is: [ " + res[0]);
                        for (int i = 1; i < numvar; ++i)
                        {
                            System.Console.Write(", " + res[i]);
                        }
                        System.Console.Write(" ]\n");
                    }
                }
            }
Exemple #10
0
      public static void Main(string[] args)
      {
        using (mosek.Env env = new mosek.Env())
        {
          using (mosek.Task task = new mosek.Task(env,0,0))
          {
            task.set_Stream( mosek.streamtype.log,new msgclass());
            int numvar = 6;
            int numcon = 5;
          

            mosek.boundkey[] 
              bkc = new mosek.boundkey[] { mosek.boundkey.up, 
                                           mosek.boundkey.fx, 
                                           mosek.boundkey.fx, 
                                           mosek.boundkey.fx, 
                                           mosek.boundkey.fx };
            double[] 
              blc = new double[] { 0.0, 0.0, 0.0, 1.3862944, 0.0 },
              buc = new double[] { 1.0, 0.0, 0.0, 1.3862944, 0.0 };

            mosek.boundkey[]
              bkx = new mosek.boundkey[] { mosek.boundkey.fr,
                                               mosek.boundkey.fr, 
                                               mosek.boundkey.fr, 
                                               mosek.boundkey.fr, 
                                               mosek.boundkey.fr, 
                                               mosek.boundkey.fr };
            double[]
              blx = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, 
              bux = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };

            long[]
              aptrb = new long[] { 0, 0, 3, 6, 8 },
              aptre = new long[] { 0, 3, 6, 8, 10 };
            int[] 
              asubi = new int[] { 0, 1, 2, 3, 4 },
              asubj = new int[] { 0, 1, 2,
                                  0, 1, 3,
                                  0, 4,
                                  1, 5 };
            double[]
              aval = new double[] {  1.0,  1.0, -1.0,
                                    -1.0, -1.0, -1.0,
                                     0.5, -1.0,
                                     1.0, -1.0 };
            
            task.appendvars(numvar);
            task.appendcons(numcon);

            task.putobjsense(mosek.objsense.minimize);

            task.putvarboundslice(0, numvar, bkx, blx, bux);
            task.putconboundslice(0, numcon, bkc, blc, buc);

            task.putarowlist(asubi, aptrb, aptre, asubj, aval );

            mosek.scopr[]
              opro  = new mosek.scopr[] { mosek.scopr.exp, 
                                              mosek.scopr.exp };
            int[] 
              oprjo = new int[] { 2, 3 };
            double[]
              oprfo = new double[] { 1.0, 1.0 },
              oprgo = new double[] { 1.0, 1.0 },
              oprho = new double[] { 0.0, 0.0 };

            mosek.scopr[]
              oprc = new mosek.scopr[] { mosek.scopr.exp, 
                                             mosek.scopr.exp };
            int[]
              opric = new int[] { 0, 0 },
              oprjc = new int[] { 4, 5 };
            double[]
              oprfc = new double[] { 1.0, 1.0 },
              oprgc = new double[] { 1.0, 1.0 },
              oprhc = new double[] { 0.0, 0.0 };

            task.putSCeval(opro, oprjo, oprfo, oprgo, oprho,
                           oprc, opric, oprjc, oprfc, oprgc, oprhc);
            
            task.optimize();
            task.solutionsummary(mosek.streamtype.msg); 
            double[] res = new double[numvar];
            task.getsolutionslice(mosek.soltype.itr,
                                  mosek.solitem.xx,
                                  0, numvar,
                                  res);

            System.Console.Write("Solution is: [ " + res[0]);
            for (int i = 1; i < numvar; ++i) System.Console.Write(", " + res[i]);
            System.Console.Write(" ]\n");
            
          }
        }
      }      
Exemple #11
0
        public void Optimize(Story story, PositionTable <double> position)
        {
            int           count = 0;
            List <double> list  = new List <double>();

            int[,] index = new int[story.Characters.Count, story.FrameCount];
            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount; ++frame)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        index[i, frame] = count++;
                        list.Add(position[i, frame]);
                    }
                }
            }

            double[] X = list.ToArray <double>();

            int[,] Q = new int[X.Length, X.Length];
            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount - 1; ++frame)
                {
                    int left  = frame;
                    int right = frame + 1;
                    if (story.SessionTable[i, left] != -1 && story.SessionTable[i, right] != -1)
                    {
                        Q[index[i, left], index[i, left]]   += 2;
                        Q[index[i, right], index[i, right]] += 2;
                        Q[index[i, left], index[i, right]]  -= 2;
                        Q[index[i, right], index[i, left]]  -= 2;
                    }
                }
            }
            List <int>    li = new List <int>();
            List <int>    lj = new List <int>();
            List <double> lv = new List <double>();

            for (int i = 0; i < X.Length; ++i)
            {
                for (int j = 0; j <= i; ++j)
                {
                    if (Q[i, j] != 0)
                    {
                        li.Add(i);
                        lj.Add(j);
                        lv.Add((double)Q[i, j]);
                    }
                }
            }
            int[]    qsubi = li.ToArray();
            int[]    qsubj = lj.ToArray();
            double[] qval  = lv.ToArray();


            List <Tuple <int, int> > listInner = new List <Tuple <int, int> >();
            List <Tuple <int, int> > listOuter = new List <Tuple <int, int> >();

            for (int frame = 0; frame < story.FrameCount; ++frame)
            {
                List <Tuple <int, double> > l = new List <Tuple <int, double> >();
                for (int i = 0; i < story.Characters.Count; ++i)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        l.Add(new Tuple <int, double>(i, position[i, frame]));
                    }
                }
                l.Sort((a, b) => a.Item2.CompareTo(b.Item2));
                for (int k = 0; k < l.Count - 1; ++k)
                {
                    int x = l[k].Item1;
                    int y = l[k + 1].Item1;
                    if (story.SessionTable[x, frame] == story.SessionTable[y, frame])
                    {
                        listInner.Add(new Tuple <int, int>(index[x, frame], index[y, frame]));
                    }
                    else
                    {
                        listOuter.Add(new Tuple <int, int>(index[x, frame], index[y, frame]));
                    }
                }
            }


            const double infinity      = 0;
            int          NumConstraint = listInner.Count + listOuter.Count;
            int          NumVariable   = X.Length;


            double[]         blx = new double[NumVariable];
            double[]         bux = new double[NumVariable];
            mosek.boundkey[] bkx = new mosek.boundkey[NumVariable];

            for (int i = 0; i < NumVariable; ++i)
            {
                bkx[i] = mosek.boundkey.fr;
            }


            int[][]    asub = new int[NumVariable][];
            double[][] aval = new double[NumVariable][];


            List <int>[]    asubList = new List <int> [NumVariable];
            List <double>[] avalList = new List <double> [NumVariable];
            for (int i = 0; i < NumVariable; ++i)
            {
                asubList[i] = new List <int>();
                avalList[i] = new List <double>();
            }
            for (int i = 0; i < listInner.Count; ++i)
            {
                Tuple <int, int> pair = listInner[i];
                int x = pair.Item1;
                int y = pair.Item2;

                asubList[x].Add(i);
                avalList[x].Add(-1);

                asubList[y].Add(i);
                avalList[y].Add(1);
            }
            for (int i = 0; i < listOuter.Count; ++i)
            {
                int j = i + listInner.Count;
                Tuple <int, int> pair = listOuter[i];
                int x = pair.Item1;
                int y = pair.Item2;
                asubList[x].Add(j);
                avalList[x].Add(-1);

                asubList[y].Add(j);
                avalList[y].Add(1);
            }
            for (int i = 0; i < NumVariable; ++i)
            {
                asub[i] = asubList[i].ToArray();
                aval[i] = avalList[i].ToArray();
            }
            mosek.boundkey[] bkc = new mosek.boundkey[NumConstraint];
            double[]         blc = new double[NumConstraint];
            double[]         buc = new double[NumConstraint];
            for (int i = 0; i < listInner.Count; ++i)
            {
                bkc[i] = mosek.boundkey.fx;
                blc[i] = 28;
                buc[i] = 28;
            }
            for (int i = listInner.Count; i < listInner.Count + listOuter.Count; ++i)
            {
                bkc[i] = mosek.boundkey.lo;
                blc[i] = 84;
                buc[i] = infinity;
            }

            mosek.Task task = null;
            mosek.Env  env  = null;
            double[]   xx   = new double[NumVariable];
            try
            {
                env = new mosek.Env();
                env.init();

                task = new mosek.Task(env, 0, 0);
                task.putmaxnumvar(NumVariable);
                task.putmaxnumcon(NumConstraint);

                task.append(mosek.accmode.con, NumConstraint);
                task.append(mosek.accmode.var, NumVariable);

                task.putcfix(0.0);

                for (int j = 0; j < NumVariable; ++j)
                {
                    task.putcj(j, 0);
                    task.putbound(mosek.accmode.var, j, bkx[j], blx[j], bux[j]);

                    task.putavec(mosek.accmode.var, j, asub[j], aval[j]);
                }

                for (int i = 0; i < NumConstraint; ++i)
                {
                    task.putbound(mosek.accmode.con, i, bkc[i], blc[i], buc[i]);
                }

                task.putobjsense(mosek.objsense.minimize);
                task.putqobj(qsubi, qsubj, qval);

                task.optimize();

                mosek.solsta solsta;
                mosek.prosta prosta;

                task.getsolutionstatus(mosek.soltype.itr,
                                       out prosta,
                                       out solsta);
                task.getsolutionslice(mosek.soltype.itr,
                                      mosek.solitem.xx,
                                      0,
                                      NumVariable,
                                      xx);
            }
            catch (mosek.Exception e)
            {
                Console.WriteLine(e.Code);
                Console.WriteLine(e);
            }
            finally
            {
                if (task != null)
                {
                    task.Dispose();
                }
                if (env != null)
                {
                    env.Dispose();
                }
            }


            for (int i = 0; i < story.Characters.Count; ++i)
            {
                for (int frame = 0; frame < story.FrameCount; ++frame)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        position[i, frame] = xx[index[i, frame]];
                    }
                }
            }
        }