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; } }
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); } }
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); } }
public ModifiedOgawaSolver(StorylineApp app) { _app = app; }
public GlobalOptimizedSolver(StorylineApp app) { _app = app; }
public SessionBreaker(StorylineApp app, Story story) { _app = app; _story = story; }
public ConstraintCalculator(StorylineApp app) { _app = app; }
public SolveManager(StorylineApp app) { _app = app; }
public LongLineConstrainedOptimizer(StorylineApp app) { _app = app; }
public AlignmentOptimizedSolver(StorylineApp app) { _app = app; }
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; })); }
public LineRelaxer(StorylineApp app) { _app = app; }
public OgawaAverageSolver(StorylineApp app) { _app = app; }
public LocationTreeSolver(StorylineApp app) { _app = app; }
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 }
public MyAverageSolver(StorylineApp app) { _app = app; }
public BundleSegmentGenerator(StorylineApp app) { _app = app; }
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 }
public LocationTreeAligner(StorylineApp app) { _app = app; }
public GradientOgawaSolver(StorylineApp app) { _app = app; }
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; } }
public PositionBasedBundleOptimizer(StorylineApp app) { _app = app; }
public BundleConverter(StorylineApp app) { _app = app; }
public NaiveAligner(StorylineApp app) { _app = app; }
public LocationSensitiveSolver(StorylineApp app) { _app = app; }