Esempio n. 1
0
        private void PutBounds(mosek.Task task, IEnumerable <int> indices)
        {
            foreach (int vid in indices)
            {
                Rational lo, hi;

                GetBounds(vid, out lo, out hi);

                mosek.boundkey bk;

                if (GetIgnoreBounds(vid))
                {
                    bk = mosek.boundkey.fr;
                }
                else
                {
                    bk = GetMosekBk(lo, hi);
                }

                if (IsRow(vid))
                {
                    task.putbound(mosek.accmode.con, rowMap[vid], bk, (double)lo, (double)hi);
                }
                else
                {
                    task.putbound(mosek.accmode.var, varMap[vid], bk, (double)lo, (double)hi);
                }
            }
        }
Esempio n. 2
0
        private bool InitSoltypeDefined(mosek.Task task, out mosek.soltype sol)
        {
            int isdef_bas;
            int isdef_itr;
            int isdef_itg;

            task.solutiondef(mosek.soltype.bas, out isdef_bas);
            task.solutiondef(mosek.soltype.itr, out isdef_itr);
            task.solutiondef(mosek.soltype.itg, out isdef_itg);

            sol = mosek.soltype.itg;

            if (isdef_bas == 0 && isdef_itr == 0 && isdef_itg == 0)
            {
                return(false);
            }

            if (isdef_itg == 1)
            {
                sol = mosek.soltype.itg;
            }

            if (isdef_bas == 1)
            {
                sol = mosek.soltype.bas;
            }
            else if (isdef_itr == 1)
            {
                sol = mosek.soltype.itr;
            }

            return(true);
        }
Esempio n. 3
0
        private void UpdateSolution(mosek.Task task)
        {
            double[]       xx  = new double[VariableCount];
            double[]       xc  = new double[RowCount];
            mosek.stakey[] skx = new mosek.stakey[VariableCount];
            mosek.stakey[] skc = new mosek.stakey[RowCount];
            mosek.soltype  sol;

            primalObjIsdef = InitSoltypeDefined(task, out solDefined);

            if (GetSoltypeDefined(out sol))
            {
                task.getsolutionstatus(
                    sol,
                    out prosta,
                    out solsta);
            }

            if (GetSoltypeDefined(out sol))
            {
                task.getsolutionstatuskeyslice(
                    mosek.accmode.var,
                    sol,
                    0,
                    VariableCount,
                    skx);

                task.getsolutionstatuskeyslice(
                    mosek.accmode.con,
                    sol,
                    0,
                    RowCount,
                    skc);

                task.getsolutionslice(
                    sol,
                    mosek.solitem.xx,
                    0,
                    VariableCount,
                    xx);

                task.getsolutionslice(
                    sol,
                    mosek.solitem.xc,
                    0,
                    RowCount,
                    xc);


                UpdateSolutionPart(RowIndices, xc, skc);
                UpdateSolutionPart(VariableIndices, xx, skx);
            }

            if (GetSoltypeDefined(out sol))
            {
                primalObjIsdef = true;
                primalObj      = task.getprimalobj(sol);
            }
        }
Esempio n. 4
0
 private void LoadData(mosek.Task task)
 {
     SetDimensions(task);
     PutA(task);
     PutBounds(task, VariableIndices);
     PutBounds(task, RowIndices);
     PutObj(task);
     SetIntergerStatus(task, Indices);
 }
Esempio n. 5
0
        private void PutObj(mosek.Task task)
        {
            if (GoalCount > 1)
            {
                throw new MosekMsfUnsupportedFeatureException("Multiple goals.");
            }

            foreach (ILinearGoal goal in Goals)
            {
                if (goal.Enabled)
                {
                    if (goal.Minimize)
                    {
                        task.putobjsense(mosek.objsense.minimize);
                    }
                    else
                    {
                        task.putobjsense(mosek.objsense.maximize);
                    }

                    if (IsRow(goal.Index))
                    {
                        goalUsed = goal;

                        double mul = -(1.0 / (double)GetCoefficient(goal.Index, goal.Index));
                        foreach (LinearEntry e in GetRowEntries(goal.Index))
                        {
                            task.putcj(varMap[e.Index], (double)e.Value * mul);
                        }
                        foreach (QuadraticEntry e in GetRowQuadraticEntries(goal.Index))
                        {
                            double mul2 = 1.0;
                            if (e.Index2 == e.Index1)
                            {
                                mul2 = 2.0;
                            }

                            /* We assume that either q_ij or q_ji is nonzero, not both.
                             * We put all elements in the lower triangular part.  */
                            int index1   = varMap[e.Index1];
                            int index2   = varMap[e.Index2];
                            int ltIndex1 = System.Math.Max(index1, index2);
                            int ltIndex2 = System.Math.Min(index1, index2);

                            task.putqobjij(ltIndex1, ltIndex2, (double)e.Value * mul * mul2);
                        }
                    }
                    else
                    {
                        task.putcj(varMap[goal.Index], 1.0);
                    }
                }
            }
        }
Esempio n. 6
0
 protected virtual void SetIntergerStatus(mosek.Task task, IEnumerable <int> indices)
 {
     foreach (int vid in indices)
     {
         if (GetIntegrality(vid))
         {
             if (IsRow(vid))
             {
                 throw new MosekMsfUnsupportedFeatureException("Integrality constraints on rows.");
             }
             else
             {
                 task.putvartype(varMap[vid], mosek.variabletype.type_int);
             }
         }
     }
 }
Esempio n. 7
0
        public void LoadMosekParams(mosek.Task task)
        {
            foreach (KeyValuePair <mosek.iparam, int> p in iparam)
            {
                task.putintparam(p.Key, p.Value);
            }

            foreach (KeyValuePair <mosek.dparam, double> p in dparam)
            {
                task.putdouparam(p.Key, p.Value);
            }

            foreach (KeyValuePair <mosek.sparam, string> p in sparam)
            {
                task.putstrparam(p.Key, p.Value);
            }
        }
Esempio n. 8
0
        private void PutA(mosek.Task task)
        {
            IEnumerable <int> vars = VariableIndices;
            IEnumerable <int> rows = RowIndices;
            int  mskColIdx         = 0;
            bool rowMult           = false; /*  If true one of the row variable coeficient differ from the default -1 and we must scale with - 1/rc */

            /* for each constraint a 'row' variable 'r' is added. the constraint becomes a^x - r == 0. The coefficient (rc = -1) of the row variable may be changed by the user.
             * This corresponds to multiplying the constraint with - 1/rc */

            foreach (int vid in rows)
            {
                if (GetCoefficient(vid, vid) != -1.0)
                {
                    rowMult = true;
                }
            }

            if (rowMult)
            {
                foreach (int vid in vars)
                {
                    foreach (LinearEntry e in GetVariableEntries(vid))
                    {
                        double mul = -(1.0 / (double)GetCoefficient(e.Index, e.Index));
                        task.putaij(rowMap[e.Index], mskColIdx, (double)e.Value * mul);
                    }
                    mskColIdx++;
                }
            }
            else
            {
                foreach (int vid in vars)
                {
                    foreach (LinearEntry e in GetVariableEntries(vid))
                    {
                        task.putaij(rowMap[e.Index], mskColIdx, (double)e.Value);
                    }
                    mskColIdx++;
                }
            }
        }
Esempio n. 9
0
        public PositionTable <double> Optimize(Story story, PositionTable <double> position)
        {
            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 && Math.Abs(position[i, frame] - position[i, frame - 1]) < 1e-5)
                        {
                            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), 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]));
                        }
                    }
                }
            }

            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] = -double.MaxValue;
                bux[i] = double.MaxValue;
            }
            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] = 0;
                buc[i] = 0;
            }
            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];
            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.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, -2 * X[j]);
                    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();
                }
            }

            PositionTable <double> result = new PositionTable <double>(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)
                    {
                        result[i, frame] = xx[index[i, frame]];
                    }
                }
            }

            return(result);
        }
Esempio n. 10
0
        public PersistentOptimizer(StorylineApp app, Story story, PositionTable <int> perm, PositionTable <int> segment, double innerDist, double outerDist)
        {
            // restore data structures
            this._app    = app;
            this.story   = story;
            this.perm    = perm;
            this.segment = segment;

            // initialize
            // index for Q at character i, timeframe j
            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] = -1; // invalid value
                }
            }
            //
            List <double> X = new List <double>();
            int count       = -1;
            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(perm[i, frame]); // assign perm to X
                        }
                    }
                }
            }
            int NumVariable = X.Count;
            xCount = X.Count;

            // calculate sparse objective matrix Q
            #region Matrix
            Dictionary <Tuple <int, int>, double> matrix = new Dictionary <Tuple <int, int>, double>();
            for (int i = 0; i < X.Count; ++i)
            {
                matrix.Add(new Tuple <int, int>(i, i), 0.1);//simon, ctk
            }
            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;
                    var leftSession  = story.SessionTable[i, left];
                    var rightSession = story.SessionTable[i, right];

                    var needBreak = false;
                    foreach (var sessionBreak in _app.Status.Config.SessionBreaks)
                    {
                        if (sessionBreak.session1 == leftSession && sessionBreak.session2 == rightSession &&
                            sessionBreak.frame == left)
                        {
                            needBreak = true;
                            break;
                        }
                    }

                    if (leftSession != -1 && rightSession != -1 && segment[i, left] != segment[i, right] && !needBreak)
                    {
                        Tuple <int, int> ll = new Tuple <int, int>(index[i, left], index[i, left]);
                        Tuple <int, int> lr = new Tuple <int, int>(index[i, left], index[i, right]);
                        Tuple <int, int> rl = new Tuple <int, int>(index[i, right], index[i, left]);
                        Tuple <int, int> rr = new Tuple <int, int>(index[i, right], index[i, right]);
                        if (!matrix.ContainsKey(ll))
                        {
                            matrix.Add(ll, 0);
                        }
                        if (!matrix.ContainsKey(lr))
                        {
                            matrix.Add(lr, 0);
                        }
                        if (!matrix.ContainsKey(rl))
                        {
                            matrix.Add(rl, 0);
                        }
                        if (!matrix.ContainsKey(rr))
                        {
                            matrix.Add(rr, 0);
                        }
                        matrix[ll] += 2;
                        matrix[rr] += 2;
                        matrix[lr] -= 2;
                        matrix[rl] -= 2;
                    }
                }
            }

            // sparse representation to matrix Q
            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 matrix)
            {
                if (pair.Key.Item1 >= pair.Key.Item2 && Math.Abs(pair.Value) > 0.000001)
                {
                    li.Add(pair.Key.Item1);
                    lj.Add(pair.Key.Item2);
                    lv.Add(pair.Value);
                }
            }
            // input must be array instead of list
            int[] qsubi   = li.ToArray();
            int[] qsubj   = lj.ToArray();
            double[] qval = lv.ToArray();
            #endregion

            // calculate inner and outer constraints
            #region Constraints
            // constraint { <index of k, index of k+1>: bundle}
            Dictionary <Tuple <int, int>, int> constraints = new Dictionary <Tuple <int, int>, int>();

            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>();
            }

            List <mosek.boundkey> bkcList = new List <boundkey>();
            List <double> blcList         = new List <double>();
            List <double> bucList         = new List <double>();

            var sessionInnerGaps = _app.Status.Config.sessionInnerGaps;
            var sessionOuterGaps = _app.Status.Config.sessionOuterGaps;
            // for each time frame
            int constraintCounter = 0;
            for (int frame = 0; frame < story.FrameCount; ++frame)
            {
                // charaters at timeframe
                List <Tuple <int, int> > l = new List <Tuple <int, int> >();
                for (int i = 0; i < story.Characters.Count; ++i)
                {
                    if (story.SessionTable[i, frame] != -1)
                    {
                        l.Add(new Tuple <int, int>(i, perm[i, frame]));
                    }
                }
                // get character order in current frame
                // apply result in location tree sort
                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;
                    // inner constraints
                    // x is upper character
                    var indexX = index[x, frame];
                    // y is lower character
                    var indexY   = index[y, frame];
                    var sessionX = story.SessionTable[x, frame];
                    var sessionY = story.SessionTable[y, frame];
                    if (sessionX == sessionY)
                    {
                        // lower character index and higher character index
                        Tuple <int, int> tuple = new Tuple <int, int>(indexX, indexY);
                        if (constraints.ContainsKey(tuple))
                        {
                            var i = constraints[tuple];
                            Debug.Assert(i >= 0);
                            // change default gaps with respect to sessionInnerGaps
                            buildInnerGapConstraints(sessionInnerGaps, sessionX, blcList, i, bucList);
                        }
                        else
                        {
                            int i = constraintCounter++;
                            // type ra for range, fx for fixed
                            bkcList.Add(mosek.boundkey.ra);
                            // add contraint of innergap +- 2
                            // lower
                            blcList.Add(Math.Max(innerDist - 2, 2));
                            // upper
                            bucList.Add(innerDist + 2);
                            buildInnerGapConstraints(sessionInnerGaps, sessionX, blcList, i, bucList);

                            // Row index of non - zeros in column i
                            // sparse array for i-th constraint
                            asubList[indexX].Add(i);
                            // Non - zero Values of column i.
                            avalList[indexX].Add(-1);
                            asubList[indexY].Add(i);
                            avalList[indexY].Add(1);
                            // positive for inner gap
                            // store the index for further modification
                            // assigned in sessionInnerGaps
                            constraints.Add(tuple, i);
                        }
                    }
                    else
                    {
                        Tuple <int, int> tuple = new Tuple <int, int>(indexX, indexY);
                        if (constraints.ContainsKey(tuple))
                        {
                            var j = constraints[tuple];
                            Debug.Assert(j <= 0);
                            j *= -1;
                            // change default gaps with respect to sessionOuterGaps
                            buildOuterGapConstraints(sessionOuterGaps, sessionX, sessionY, blcList, j, bucList, bkcList);
                        }
                        else
                        {
                            int j = constraintCounter++;
                            // default setting
                            bkcList.Add(mosek.boundkey.lo);
                            blcList.Add(outerDist);
                            bucList.Add(1000);
                            buildOuterGapConstraints(sessionOuterGaps, sessionX, sessionY, blcList, j, bucList, bkcList);
                            asubList[indexX].Add(j);
                            avalList[indexX].Add(-1);
                            asubList[indexY].Add(j);
                            avalList[indexY].Add(1);
                            // negative for outer gap
                            // store the index for further modification
                            // assigned in sessionInnerGaps
                            constraints.Add(tuple, -j);
                        }
                    }
                }
            }

            foreach (KeyValuePair <Tuple <int, int>, int> pair in constraints)
            {
                if (pair.Value >= 0)
                {
                    innerList.Add(pair.Key);
                }
                else
                {
                    outerList.Add(pair.Key);
                }
            }
            int NumConstraint = innerList.Count + outerList.Count;

            // to array
            int[][] asub    = new int[NumVariable][];
            double[][] aval = new double[NumVariable][];

            for (int i = 0; i < NumVariable; ++i)
            {
                asub[i] = asubList[i].ToArray();
                aval[i] = avalList[i].ToArray();
            }

            mosek.boundkey[] bkc = bkcList.ToArray();
            double[] blc         = blcList.ToArray();
            double[] buc         = bucList.ToArray();
            Debug.Assert(constraintCounter == NumConstraint);
            #endregion

            // calculate variable bound
            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;
            }

            // addCharacterYConstraints in a +- 10 range
            foreach (var yConstraint in _app.Status.Config.CharacterYConstraints)
            {
                if (yConstraint.frame < 0 || yConstraint.frame > story.FrameCount)
                {
                    continue;
                }
                var i = index[yConstraint.characterId, yConstraint.frame];
                if (i != -1)
                {
                    blx[i] = yConstraint.lowerY;
                    bux[i] = yConstraint.upperY;
                }
            }

            // setup mosek
            #region Mosek
            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);
            }
            catch (mosek.Exception e)
            {
                Console.WriteLine(e.Code);
                Console.WriteLine(e);
            }
            #endregion
        }
Esempio n. 11
0
        public LODOptimizer(StorylineApp app, List <Node>[] _nodePool)
        {
            _app     = app;
            nodePool = _nodePool;
            count    = 0;
            for (int frame = 0; frame < nodePool.Count(); frame++)
            {
                foreach (Node node in nodePool[frame])
                {
                    if (frame > 0 && node.alignPrev != null)
                    {
                        index.Add(node, index[node.alignPrev]);
                    }
                    else
                    {
                        index.Add(node, count++);
                    }
                }
            }
            int NumVariable = index.Count;

            #region Matrix
            var matrix = new Dictionary <Tuple <int, int>, double>();
            for (int i = 0; i < index.Count; ++i)
            {
                matrix.Add(new Tuple <int, int>(i, i), 0.01);//simon
            }
            for (int frame = 0; frame < nodePool.Count() - 1; frame++)
            {
                foreach (Node left in nodePool[frame])
                {
                    foreach (Node right in nodePool[frame + 1])
                    {
                        if (left.alignNext != right)//这样才有可能算进(yi-yj)^2里
                        {
                            int weight          = left.segments.Intersect(right.segments).Count();
                            Tuple <int, int> ll = new Tuple <int, int>(index[left], index[left]);
                            Tuple <int, int> lr = new Tuple <int, int>(index[left], index[right]);
                            Tuple <int, int> rl = new Tuple <int, int>(index[right], index[left]);
                            Tuple <int, int> rr = new Tuple <int, int>(index[right], index[right]);
                            if (!matrix.ContainsKey(ll))
                            {
                                matrix.Add(ll, 0);
                            }
                            if (!matrix.ContainsKey(lr))
                            {
                                matrix.Add(lr, 0);
                            }
                            if (!matrix.ContainsKey(rl))
                            {
                                matrix.Add(rl, 0);
                            }
                            if (!matrix.ContainsKey(rr))
                            {
                                matrix.Add(rr, 0);
                            }
                            matrix[ll] += weight;
                            matrix[rr] += weight;
                            matrix[lr] -= weight;
                            matrix[rl] -= weight;
                        }
                    }
                }
            }
            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 matrix)
            {
                if (pair.Key.Item1 >= pair.Key.Item2 && pair.Value != 0)
                {
                    li.Add(pair.Key.Item1);
                    lj.Add(pair.Key.Item2);
                    lv.Add(pair.Value);
                }
            }
            int[]    qsubi = li.ToArray();
            int[]    qsubj = lj.ToArray();
            double[] qval  = lv.ToArray();
            #endregion

            #region Constraints
            for (int frame = 0; frame < nodePool.Count(); frame++)
            {
                for (int i = 0; i < nodePool[frame].Count - 1; i++)
                {
                    var nodeUp   = nodePool[frame][i];
                    var nodeDown = nodePool[frame][i + 1];
                    if (nodeUp.type == NodeType.Segment && nodeDown.type == NodeType.Segment &&
                        nodeUp.parent == nodeDown.parent)
                    {
                        inner.Add(new Tuple <int, int>(index[nodeUp], index[nodeDown]));
                    }
                    else
                    {
                        outer.Add(new Tuple <int, int>(index[nodeUp], index[nodeDown]));
                    }
                }
            }
            int             NumConstraint = inner.Count + outer.Count;
            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 < inner.Count; i++)
            {
                Tuple <int, int> pair = inner[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 < outer.Count; i++)
            {
                int j = i + inner.Count;
                Tuple <int, int> pair = outer[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 < inner.Count; ++i)
            {
                bkc[i] = mosek.boundkey.fx;
                blc[i] = _app.Status.Config.Style.DefaultInnerGap;
                buc[i] = _app.Status.Config.Style.DefaultInnerGap;
            }
            for (int i = inner.Count; i < inner.Count + outer.Count; ++i)
            {
                bkc[i] = mosek.boundkey.lo;
                blc[i] = _app.Status.Config.Style.OuterGap;
                buc[i] = 1000;
            }
            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;
            }
            #endregion

            #region Mosek
            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);
            }
            catch (mosek.Exception e)
            {
                Console.WriteLine(e.Code);
                Console.WriteLine(e);
            }
            #endregion
        }
Esempio n. 12
0
 private void SetDimensions(mosek.Task task)
 {
     task.putmaxnumanz(CoefficientCount);
     task.append(mosek.accmode.con, RowCount);
     task.append(mosek.accmode.var, VariableCount);
 }
Esempio n. 13
0
        public virtual ILinearSolution Solve(ISolverParameters parameters)
        {
            lock (classLock)
            {
                if (env != null) /* If shutdown has already been called, env may be null.  */
                {
                    mosek.Task task = null;
                    task = new mosek.Task(env, 0, 0);
                    task.set_Stream(mosek.streamtype.log, null);
                    task.set_Stream(mosek.streamtype.msg, null);
                    task.set_Stream(mosek.streamtype.err, null);

                    MosekSolverParams mosekParams = parameters as MosekSolverParams;

                    interrupted    = false;
                    primalObjIsdef = false;

                    foreach (System.Diagnostics.TraceListener listener in mosekParams.GetListeners())
                    {
                        msgStream.AddListener(listener);
                    }

                    if (msgStream.listeners.Count > 0)
                    {
                        task.set_Stream(mosek.streamtype.log, msgStream);
                    }

                    mosekParams.LoadMosekParams(task);
                    progressCB = new MosekProgress(parameters.QueryAbort);

                    task.ProgressCB = progressCB;

                    if (disposed)
                    {
                        progressCB.Abort();
                    }

                    LoadData(task);

                    if (mosekParams.TaskDumpFileName != null)
                    {
                        task.writedata(mosekParams.TaskDumpFileName);
                    }

                    try
                    {
                        task.optimize();
                    }
                    catch (mosek.Warning w)
                    {
                        if (w.Code == mosek.rescode.trm_user_callback)
                        {
                            interrupted = true;
                            // feasible solutions ?
                            if (task.getintinf(mosek.iinfitem.mio_num_int_solutions) > 0)
                            {
                                foundIntSolution = true;
                            }
                        }
                    }
                    catch (mosek.Error e)
                    {
                        throw new MosekMsfException(e.ToString());
                    }

                    if (task.getintinf(mosek.iinfitem.mio_num_relax) > 0)
                    {
                        mipBestBound = task.getdouinf(dinfitem.mio_obj_bound);
                    }

                    task.solutionsummary(mosek.streamtype.log);

                    UpdateSolution(task);
                    progressCB = null;
                    if (task != null)
                    {
                        task.Dispose();
                        task = null;
                    }
                }
            }

            ILinearSolution sol = CreateLinearSolution();

            return(sol);
        }