【发布时间】:2015-03-27 00:57:33
【问题描述】:
这个问题更多的是关于一种有效的算法而不是实现,所以我不会发布代码。 (不会真正帮助您理解问题)
向您介绍这个问题: 我正在开发一个程序来计算 automovilistics 崩溃报告。它为您提供了一系列“equations”(Eq 从现在开始,Eqs 表示复数),您可以在其中输入数据并通常得到 n 个结果。
例如:您选择覆盖的空间(x),其中输入时间(t),加速度(a)和初始速度(v),然后x =(a*t)+((a*t^2)/ 2)。 问题是这个 Eqs 在一个 object 里面,它包含很多东西,而不是 vars 和 ecuation 本身,我们称之为 Bo(我正在谈论的 busssines 对象。
所以 BO 它相当大(并且需要),除此之外,1 Bo 可以有 N 个 Eq,并且不止一个结果,此外,每个 Eq 都可以将值范围作为输入,这让你得到好吧...(假设您只能在 2 个变量上使用范围,实际上这不受限制)因此您将获得每个结果的结果表(一些 Bos 有 4 个不同的结果)。范围的步数有上限,第一个范围为 20 个,第二个范围为 10 个。 (在一个有 4 个结果的 Bo 中,将映射到 1 个 Bo 的 800 个结果)。
顺便说一句,我必须将这个 Bos 及其各自的结果存储(保存在文件中),并且 Var 输入每次都无法在运行时计算它们(我可以只保存 ecuation 和 var 输入并计算结果每次我需要它们时),因为Bos可以更改它们,并且用户需要保留以前的结果,不要问..
此外,您可以将 Bo 的一个结果导入到另一个 Bo 的 Eq 输入中。 所以在前面的例子中(我们称之为 Bo1)加速度可能来自另一个计算它的 Bo (Bo2),并采用其他参数来计算它,如果你改变 Bo2 的输入,结果会改变,所以至少 1 Bo1 的 var 会发生变化,从而使 Bo1 的结果发生变化。这可以级联(B2 从 B3 导入等等)。一个 Bo 可以从其他 N 个 Bos 导入其所有 N 个变量。
我不能使用指针或引用类型(也许可以使用引用类型,无论如何这将是很多工作,必须处理来自不同用户的先前保存的数据,以及对象缺少引用等)。
我决定只使用数组的集合,在每个数组中存储,{Id_of_Bo_Exporting, Id_Bo_importing,Id_Variable_of_Bo_Importing,..(ohters ids to map the especific result exporting)} 数组是 int 的(前 2 个很长) .
我不太喜欢它,但代码运行良好。 (感谢阅读)我保证,问题来了。
问题是,我必须检查循环进口,如果 B3 从 B2 进口和 B2 从 B1 进口,我不应该允许从 B3(或 B2)进口 Bo1。这将导致无限循环,(我可以停止循环,但从数学角度来看,这不是允许导入的逻辑)。
还有导入列表,最终可能会很长,
我想到了一个 ArrayList> 所以每次我添加一个导入时,我都会在这个我不喜欢的“东西”上添加 Id。 (arraylist的arraylist)
每个 long 数组的第一个位置都会有“Bo id 标头”,每次 Bo 导入时,新的 Id 都会添加到其列表中,并且每个其他 Bo 都会导入 Bo(进行导入的那个)。
因此,如果我的用户尝试从 B1 生成 B9,该方法将检测到,B1 正在被添加到自己的列表中并且不会允许。
实现非常简单。 (让我们使用 java,不,我使用的是 .net,没有自己启动项目)
示例 {{}}
B1 从 B2 导入: {{B1,B2}}
B1 从 B6 导入: {{B1,B2,B6}}
B2 从 B4 导入: {{B1,B2,B6,B4},{B2,B4}}
B4 从 B9 导入: {{B1,B2,B3,B4,B9},{B2,B4,B9},{B4,B9}}
B3 从 B10 导入: {{B1,B2,B3,B4,B9,B10},{B2,B4,B9},{B4,B9},{B3,B10}}
每个 long 数组的第一个位置都会有“Bo id 标头”,每次 Bo 导入时,新的 Id 都会添加到其列表中,并且每个其他 Bo 都会导入 Bo(进行导入的那个)。
因此,如果我的用户尝试从 B1 生成 B9,该方法将检测到,B1 正在被添加到自己的列表中并且不会允许。
实现非常简单。 (让我们使用 java,不,我使用的是 .net,没有自己启动项目)
private boolean checkCircularity(long ida,long idb){
//ida importing, idb exporting
// asume List is public and called iL
// Clone il to restore it in case}
for (int i = 0 ; i < iL.size() ;i++)
// Each arraylist of long in the big array iL
{
// I would use some kind of SetUniqueList, dont know in c#
// but i could check it if needed and add it if it doesnt exist
if (iL.get(i).contains(ida))
{
if (((iL.get(i)).get(0)) == idb)
{// Circiut, breaks for's restore the original list and returns false
}
else{
if (!iL.get(i).contains(idb)) {iL.get(i).add(idb);}
}
}
} return true; }
现在的问题(使用 ListSet 或其他什么)你能想出一个更有效的方法来做到这一点吗? 两个列表(导入和 iL 可以很快变大,具体取决于用户)。 字幕速度很快。
【问题讨论】:
-
我可以确认一下 - 您正在寻找有关检测导入循环的算法的建议吗?从标题看不清楚。
标签: algorithm collections cycle-detection