Example #1
0
        protected override async void OnMessage(MessageEventArgs e)
        {
            var rawString = e.Data;
            var request   = JsonConvert.DeserializeObject <Request <Object> >(rawString);

            switch (request.action)
            {
            case ACTION_SET_ID:
                id    = JsonConvert.DeserializeObject <Request <string> >(rawString).payload;
                Story = await Task.Factory.StartNew(() => Story.Read(GetTargetFile(id)));

                break;

            case ACTION_UPDATE_LAYOUT:

                if (Story == null)
                {
                    // fail
//                                Send();
                }
                else
                {
                    var updateRequest = JsonConvert.DeserializeObject <Request <UpdateRequest> >(rawString)
                                        .payload;
                    var storylineApp = new StorylineApp();
                    LayoutHandler.ApplyUpdateConfig(updateRequest, storylineApp);
                    await Task.Factory.StartNew(() => storylineApp.SolveStory(Story));

                    var result = await LayoutHandler.postProcess(storylineApp._relaxedPos, Story, storylineApp);

                    Send(JsonConvert.SerializeObject(result));
                }
                break;
            }
        }
Example #2
0
        public async Task <LayoutResult> handleLayout(string id)
        {
            string filePath = GetTargetFile(id);

            if (File.Exists(filePath))
            {
                var story = await Task.Factory.StartNew(() => Story.Read(filePath));

                var storylineApp = new StorylineApp();
                await Task.Factory.StartNew(() => storylineApp.SolveStory(story));

                var result = await postProcess(storylineApp._relaxedPos, story, storylineApp);

                return(result);
            }
            else
            {
                return(null);
            }
        }
Example #3
0
        public async Task <LayoutResult> updateLayout(UpdateRequest updateRequest)
        {
            string filePath = GetTargetFile(updateRequest.id);

            if (File.Exists(filePath))
            {
                var story = await Task.Factory.StartNew(() => Story.Read(filePath));

                var storylineApp = new StorylineApp();

                ApplyUpdateConfig(updateRequest, storylineApp);

                await Task.Factory.StartNew(() => storylineApp.SolveStory(story));

                var result = await postProcess(storylineApp._relaxedPos, story, storylineApp);

                return(result);
            }
            else
            {
                return(null);
            }
        }
Example #4
0
 public ModifiedOgawaSolver(StorylineApp app)
 {
     _app = app;
 }
 public GlobalOptimizedSolver(StorylineApp app)
 {
     _app = app;
 }
Example #6
0
 public SessionBreaker(StorylineApp app, Story story)
 {
     _app   = app;
     _story = story;
 }
Example #7
0
 public ConstraintCalculator(StorylineApp app)
 {
     _app = app;
 }
Example #8
0
 public SolveManager(StorylineApp app)
 {
     _app = app;
 }
 public LongLineConstrainedOptimizer(StorylineApp app)
 {
     _app = app;
 }
 public AlignmentOptimizedSolver(StorylineApp app)
 {
     _app = app;
 }
Example #11
0
        public static Task <LayoutResult> postProcess(Tuple <double, double, double>[][] relaxedPos, Story story, StorylineApp app)
        {
            if (relaxedPos.Length != story.Characters.Count)
            {
                throw new ArgumentException("relaxedPos mismatched story.characters.");
            }

            return(Task.Factory.StartNew(() =>
            {
                LayoutResult result = new LayoutResult();
                result.sessionTable = new List <List <int> >();
                result.perm = new List <List <int> >();

                for (int i = 0; i < story.Characters.Count; i++)
                {
                    var character = story.Characters[i];
                    var id = character.Id == 0 ? i : character.Id;
                    var characterInfo = new CharacterInfo();
                    characterInfo.character_id = id;
                    characterInfo.name = character.Name;
                    var positions = relaxedPos[i];
                    characterInfo.points.AddRange(positions);
                    result.array.Add(characterInfo);

                    var characterFrameSession = new List <int>();
                    for (int j = 0; j < story.FrameCount; j++)
                    {
                        characterFrameSession.Add(story.SessionTable[i, j]);
                    }
                    result.sessionTable.Add(characterFrameSession);

                    var permOfChar = new List <int>();
                    for (int j = 0; j < story.FrameCount; j++)
                    {
                        permOfChar.Add(app._perm[i, j]);
                    }
                    result.perm.Add(permOfChar);
                }

                return result;
            }));
        }
Example #12
0
 public LineRelaxer(StorylineApp app)
 {
     _app = app;
 }
Example #13
0
 public OgawaAverageSolver(StorylineApp app)
 {
     _app = app;
 }
Example #14
0
 public LocationTreeSolver(StorylineApp app)
 {
     _app = app;
 }
Example #15
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
        }
Example #16
0
 public MyAverageSolver(StorylineApp app)
 {
     _app = app;
 }
 public BundleSegmentGenerator(StorylineApp app)
 {
     _app = app;
 }
Example #18
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
        }
Example #19
0
 public LocationTreeAligner(StorylineApp app)
 {
     _app = app;
 }
Example #20
0
 public GradientOgawaSolver(StorylineApp app)
 {
     _app = app;
 }
Example #21
0
        public static void ApplyUpdateConfig(UpdateRequest updateRequest, StorylineApp storylineApp)
        {
            var statusConfig = storylineApp.Status.Config;

            if (updateRequest == null)
            {
                return;
            }
            if (updateRequest.sessionInnerGap != 0.0)
            {
                statusConfig.Style.DefaultInnerGap = updateRequest.sessionInnerGap;
            }

            if (updateRequest.sessionOuterGap != 0)
            {
                statusConfig.Style.OuterGap = updateRequest.sessionOuterGap;
            }

            if (updateRequest.sessionInnerGaps != null)
            {
                statusConfig.sessionInnerGaps = updateRequest.sessionInnerGaps;
            }

            if (updateRequest.characterYConstraints != null)
            {
                statusConfig.CharacterYConstraints = updateRequest.characterYConstraints;
            }

            if (updateRequest.orders != null)
            {
                statusConfig.Orders.Clear();
                updateRequest.orders.ForEach(ints =>
                {
                    statusConfig.Orders.Add(new Tuple <int, int>(ints[0], ints[1]));
                });
            }

            if (updateRequest.orderTable != null)
            {
                statusConfig.OrderTable.Clear();
                updateRequest.orderTable.ForEach(pair =>
                {
                    statusConfig.OrderTable.Add(new Tuple <int, List <int> >(pair.Item1, pair.Item2));
                });
            }

            if (updateRequest.sessionOuterGaps != null)
            {
                statusConfig.sessionOuterGaps = updateRequest.sessionOuterGaps;
            }

            if (updateRequest.groupIds != null)
            {
                statusConfig.GroupIds = updateRequest.groupIds;
            }

            if (updateRequest.selectedSessions != null)
            {
                statusConfig.SelectedSessions = updateRequest.selectedSessions;
            }

            if (updateRequest.majorCharacters != null)
            {
                storylineApp.Status.Config.MajorCharacters = updateRequest.majorCharacters;
            }

            if (updateRequest.sessionBreaks != null)
            {
                statusConfig.SessionBreaks = updateRequest.sessionBreaks;
            }
        }
Example #22
0
 public PositionBasedBundleOptimizer(StorylineApp app)
 {
     _app = app;
 }
Example #23
0
 public BundleConverter(StorylineApp app)
 {
     _app = app;
 }
Example #24
0
 public NaiveAligner(StorylineApp app)
 {
     _app = app;
 }
Example #25
0
 public LocationSensitiveSolver(StorylineApp app)
 {
     _app = app;
 }