【发布时间】:2018-04-13 23:35:08
【问题描述】:
我一直在与一个问题作斗争,我似乎可以弄清楚如何解决它。我不会给出确切的问题,但我会将其翻译成更简单的形式。这是我想出的最简单的形式:
问题:
您有一个具有一些属性的对象类型:例如。对象 OBJ(p1, p2, z)
你有4套:A、B、C、D;它由上述对象组成。每组有 80 个对象。 (80 个 A 对象,80 个 B 对象,依此类推。这是一个数据库。)
作为输入,我给出 Z = zA + zB + zC + zD。在单词中,Z 是集合中'z' 的总和。
我对看起来像 R(Ax, Bx, Cx, Dx) 的结果集感兴趣,其中“x”代表索引(可以是 1 到 80)。
最大的那个。公式:(大约:D,它的一个数字)
最大 = coef1*(Ap1+Bp1+Cp1+Dp1) + coef2*(Ap2+Bp2+Cp2+Dp2)
coef1 和 coef2 - 系数; A、B、C、D OBJ 对象; p1 和 p2 对象属性。
我是怎么做的;也许有更好的方法??
我将 Z 小于或等于给定 Z 的所有结果集放在一个列表中。前 R1(A1、B1、C1、D1); R2(A1,B1,C1,D2)等等。 80x80x80x80 = 41 百万组合(大约)
然后我在列表中搜索使用上述公式计算的最大 SET。
我需要什么
当结果列表太大时,我在创建结果列表时出现堆栈溢出(它最多可以有 4100 万个条目,它会在大约(最多)60 万个条目后破裂)
计算需要这么长时间(找到最大的集合),我怎样才能减少时间(线程,smth else?)
全新的解决方案,解决问题。
我用 C# (Visual Studio) 编写代码。我不是在寻找解决这个问题的完整代码,而是寻找指南和/或可能的新方法。我认为我的方法不太适合它。
谢谢!
这就是我现在的做法:
public static void CalculateArmorStats(string selectedHead, string selectedChest, string selectedHands, string selectedLegs)
{
#region variable
double strike; double slash; double thrust;
double magic; double fire; double lightning; double dark;
if (!selectedHead.Contains("Name =")) selectedHead = "Name ='" + selectedHead + "'";
if (!selectedChest.Contains("Name =")) selectedChest = "Name ='" + selectedChest + "'";
if (!selectedHands.Contains("Name =")) selectedHands = "Name ='" + selectedHands + "'";
if (!selectedLegs.Contains("Name =")) selectedLegs = "Name ='" + selectedLegs + "'";
MainWindow.possibleArmors = MainWindow.possibleArmors + 1;
#endregion variable
#region calculate stats
strike = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(4).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(4).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(4).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(4).ToString());
slash = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(5).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(5).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(5).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(5).ToString());
thrust = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(6).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(6).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(6).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(6).ToString());
magic = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(7).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(7).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(7).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(7).ToString());
fire = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(8).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(8).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(8).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(8).ToString());
lightning = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(9).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(9).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(9).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(9).ToString());
dark = double.Parse(MainWindow.dbHead.Select(selectedHead).Single().ItemArray.ElementAt(10).ToString())
+ double.Parse(MainWindow.dbChest.Select(selectedChest).Single().ItemArray.ElementAt(10).ToString())
+ double.Parse(MainWindow.dbHands.Select(selectedHands).Single().ItemArray.ElementAt(10).ToString())
+ double.Parse(MainWindow.dbLegs.Select(selectedLegs).Single().ItemArray.ElementAt(10).ToString());
#endregion calculate stats
#region calculate armor
if (strike + slash + thrust > MainWindow.physicalVerifier)
{
MainWindow.physicalVerifier = strike + slash + thrust;
MainWindow.SELECTEDARMOR[0].headArmor = selectedHead;
MainWindow.SELECTEDARMOR[0].chestArmor = selectedChest;
MainWindow.SELECTEDARMOR[0].handsArmor = selectedHands;
MainWindow.SELECTEDARMOR[0].legsArmor = selectedLegs;
}
if (magic + fire + lightning + dark > MainWindow.elementalVerifier)
{
MainWindow.elementalVerifier = magic + fire + lightning + dark;
MainWindow.SELECTEDARMOR[1].headArmor = selectedHead;
MainWindow.SELECTEDARMOR[1].chestArmor = selectedChest;
MainWindow.SELECTEDARMOR[1].handsArmor = selectedHands;
MainWindow.SELECTEDARMOR[1].legsArmor = selectedLegs;
}
if (strike + slash + thrust + 0.7 * (magic + fire + lightning + dark) > MainWindow.overallVerifier)
{
MainWindow.overallVerifier = strike + slash + thrust + 0.7 * (magic + fire + lightning + dark);
MainWindow.SELECTEDARMOR[2].headArmor = selectedHead;
MainWindow.SELECTEDARMOR[2].chestArmor = selectedChest;
MainWindow.SELECTEDARMOR[2].handsArmor = selectedHands;
MainWindow.SELECTEDARMOR[2].legsArmor = selectedLegs;
}
#endregion calculate armor
}
然后我调用以下 FOR(计算需要 3 分钟 - 我怎样才能减少这个时间):
foreach (ArmorObject chestItem in MainWindow.CHESTS)
{
foreach (ArmorObject legsItem in MainWindow.LEGS)
{
foreach (ArmorObject handsItem in MainWindow.HANDS)
{
if (availableWeight >= double.Parse(chestItem.weight.ToString()) + double.Parse(legsItem.weight.ToString())
+ double.Parse(handsItem.weight.ToString()))
{
string selectedHead = MainWindow.mySlectedArmorName.head.Content.ToString();
string selectedChest = chestItem.name;
string selectedHands = handsItem.name;
string selectedLegs = legsItem.name;
CalculateArmorStats(selectedHead, selectedChest, selectedHands, selectedLegs);
}
}
}
}
好的,再次更新。 所以我做了以下事情:
我将 4 个数据库(头部、胸部、...)放在 4 个对象列表中。 -> 这会使程序启动较慢,但幅度不大。
现在,当我计算数据时,我不需要询问数据库(区域计算统计信息)-> 这将我在此处发布的 FOR 时间从 3 分钟减少到 3 秒。
但是我仍然不满意或不同意这是一个解决方案(它确实对我有帮助),因为与现实生活中的项目相比,我的数据库很小:D。
【问题讨论】:
-
最好根据您的尝试方式向我们提供
code,给我们一堆xyz变量并没有帮助。
标签: java c# math data-structures processing-efficiency