private void proc_getOptimalSol(ref StringBuilder sb, String cmd, long fromQQ, long fromGroup) { sb.AppendLine("排刀中..."); sb.AppendLine("==========="); try { if (fromGroup == 0) { sb.AppendLine("请在群中使用"); } else if (!DBManager.checkManager(fromGroup, fromQQ)) { sb.AppendLine("该操作需要大量资源,因此仅限群管使用。"); return; } Match match = rx_arrange.Match(cmd); int shukai = -1; int bossid = -1; int percent = 50; long remaining = -1; if (fromGroup != 0) { DBManager.getDefault(fromGroup, out shukai, out bossid); } int shukai_override; int boss_override; if ((match.Groups["shukai"] != null) && int.TryParse(match.Groups["shukai"].Value, out shukai_override)) { shukai = shukai_override; } if ((match.Groups["boss"] != null) && int.TryParse(match.Groups["boss"].Value, out boss_override)) { bossid = boss_override; } if (match.Groups["percent"] != null && int.TryParse(match.Groups["percent"].Value.Trim(), out percent)) { sb.AppendLine($"使用概率{percent}%进行伤害计算。"); } else { sb.AppendLine($"使用概率50%进行伤害计算。"); percent = 50; } if (shukai == -1) { sb.AppendLine("周目数读取失败"); return; } if (bossid == -1) { sb.AppendLine("Boss序号读取失败"); return; } sb.AppendLine($"周目:{shukai}"); sb.AppendLine($"Boss:{bossid}"); if (long.TryParse(match.Groups["rem"].Value, out remaining)) { sb.AppendLine($"残余血量:{remaining}"); } else { sb.AppendLine("残余血量读取失败。"); return; } sb.AppendLine("==========="); List <Dictionary <String, Object> > results = DBManager.searchGroupRecord(fromGroup, "", shukai, bossid, false); sb.AppendLine($"有相关记录{results.Count}条"); // Now group them into teams, find gaussian. Dictionary <String, List <int> > teamedDamages = new Dictionary <string, List <int> >(); // Group into accounts and teams. foreach (Dictionary <String, Object> iter in results) { String temp_key = $"[CQ:at,qq={iter["qq_num"]}] [队伍:{iter["team"]}]"; if (!teamedDamages.ContainsKey(temp_key)) { teamedDamages[temp_key] = new List <int>(); } teamedDamages[temp_key].Add((int)iter["damage"]); } sb.AppendLine($"整合后有{teamedDamages.Keys.Count}个队伍"); if (teamedDamages.Keys.Count > 90) { sb.AppendLine("啊 这队伍数量太多了(最多90个)"); sb.AppendLine("请各位先删除掉不参战的队伍(使用指令“队伍列表”查看登记的队伍,“查询 周目=xxx BOSS=xx” 查看记录,然后“删除 队伍=<队伍名>” 删掉不用的队伍)"); return; } // Find Gaussian for each team. Dictionary <String, Double> predictedDamages = new Dictionary <string, double>(); foreach (KeyValuePair <String, List <int> > e in teamedDamages) { GaussianRV ngv = new GaussianRV(); ngv.addAll(e.Value); ngv.calculate(); predictedDamages.Add(e.Key, ngv.topPercent(percent)); } // Start solving. SubSetSums solver = new SubSetSums(); solver.addChoices(predictedDamages); List <String> solution = solver.sumTo(remaining); if (solution.Count == 0) { sb.AppendLine("所有人一起上也不够哦"); } else { StringBuilder sb2 = new StringBuilder(); double count = 0; foreach (String team in solution) { sb2.AppendLine($"{team} 预估伤害{predictedDamages[team]}"); count += predictedDamages[team]; } sb.AppendLine($"以下是解法,总伤害为{count}"); sb.AppendLine(sb2.ToString()); } } catch (Exception e) { sb.AppendLine("该炸了"); } }
private void proc_sumRecord(ref StringBuilder sb, String cmd, long fromQQ, long fromGroup) { sb.AppendLine("正在统计您的战况"); sb.AppendLine("==========="); Match matches = rx_sumRecord.Match(cmd); String team = ""; int shukai = -1; int bossid = -1; team = matches.Groups["team"].Value.Trim(); if (fromGroup != 0) { DBManager.getDefault(fromGroup, out shukai, out bossid); } int shukai_override; int boss_override; if ((matches.Groups["shukai"] != null) && int.TryParse(matches.Groups["shukai"].Value, out shukai_override)) { shukai = shukai_override; } if ((matches.Groups["boss"] != null) && int.TryParse(matches.Groups["boss"].Value, out boss_override)) { bossid = boss_override; } if (shukai == -1) { sb.AppendLine("周目数识别失败。"); sb.AppendLine("==========="); return; } if (bossid == -1) { sb.AppendLine("Boss序号识别失败"); sb.AppendLine("==========="); return; } sb.AppendLine($"队伍:{team}"); sb.AppendLine($"周目数:{shukai}"); sb.AppendLine($"Boss序号:{bossid}"); sb.AppendLine("==========="); try { List <Dictionary <String, Object> > results = DBManager.searchRecord(fromQQ, team, shukai, bossid, false); sb.AppendLine($"在此条件下 您共有{results.Count}条记录。"); if (results.Count == 0) { return; } GaussianRV grv = new GaussianRV(); foreach (Dictionary <String, Object> record in results) { grv.addObservation((int)record["damage"]); } grv.calculate(); sb.AppendLine($"在25%的情况下,您可打出{Math.Round(grv.topPercent(25), 2)}的伤害,置信度{Math.Round(grv.confidence(25) * 100)}%"); sb.AppendLine($"在50%的情况下,您可打出{Math.Round(grv.topPercent(50), 2)}的伤害,置信度{Math.Round(grv.confidence(50) * 100)}%"); sb.AppendLine($"在75%的情况下,您可打出{Math.Round(grv.topPercent(75), 2)}的伤害,置信度{Math.Round(grv.confidence(75) * 100)}%"); sb.AppendLine($"在90%的情况下,您可打出{Math.Round(grv.topPercent(90), 2)}的伤害,置信度{Math.Round(grv.confidence(90) * 100)}%"); sb.AppendLine("添加更多记录可能提高置信度。"); } catch (Exception e) { sb.AppendLine("统计失败(什么东西炸了?)"); } }