ArrayList的ArrayList(用于循环检测)

时间:2015-01-28 07:37:24

标签: algorithm collections cycle-detection

这个问题更多的是关于一个有效的算法而不是实现,所以我不会发布代码。 (不会真的帮助你理解这个问题)

向您介绍以下问题: 我正在开发一个程序来计算automovilistics崩溃报告。它为您提供了一系列" 方程式" ( Eq 从现在开始,Eqs为复数形式),您可以在其中输入数据并获得n个结果。

例如:你选择空间覆盖(x),其中和输入时间(t),aceleration(a)和初始速度(v),然后x =(a * t)+((a * t ^ 2)/ 2)。 事情就是这个Eqs在一个对象里面,它包含了很多东西而不是变量本身,我们称之为 Bo (我正在谈论的busssines对象。< / p>

所以BO非常大(并且需要),除了其他东西之外,1 Bo可以有N个Eqs,并且不止一个结果,每个Eq都可以将值范围作为输入,这会让你得到好吧...(假设你只能使用2个变量的范围,实际上这不受限制)所以你将得到每个结果的结果表(一些Bos有4个不同的结果)。范围的Te步骤上限为20个第一范围,10秒范围。 (在Bo中有4个结果,可以映射800个结果为1 Bo)。

顺便说一下,我必须存储(保存在文件中)这个Bos及其各自的结果,并且Var imputs每次都不能在运行时计算它们(我可以保存ecuations,并且var imputs and calculate每次我需要它们的结果),因为Bos可以改变效果,并且用户需要保持优势结果,不要问......

此外,您可以将Bo的一个结果导入另一个Bo的Eq输入。 所以在前面的例子中(让我们称之为Bo1),aceleration可能来自另一个计算它的Bo(Bo2),并且需要其他参数来计算它,如果你改变了Bo2的输入,结果会改变,所以至少1 bo1的变量将改变,使得Bo1的结果发生变化。这可以级联(B2从B3导入,依此类推)。并且一个Bo可以从其他N个Bos中导入所有N个变量。

我不能使用指针或引用类型(也许可以使用引用类型,无论如何,这将是很多工作,必须使用来自不同用户的先前保存的数据,并且对象缺少引用等)。 / p>

我决定只使用一组数组,在每个数组中存储,{Id_of_Bo_Exporting,Id_Bo_importing,Id_Variable_of_Bo_Importing,...(用于映射特定结果导出的ohters id)}数组为int(前2个长)

我不是很喜欢它,但代码工作得很好。 (感谢阅读)问题是我的继承人的儿子。

问题是,我必须检查圆周进口,如果B3从B2进口B2和B2进口,我不允许从B3(或B2)进口Bo1。这将导致无限循环,(我可以停止循环但不是数学视图中的逻辑以允许导入)。

和导入列表,最终可能很长,

我想要一个ArrayList&lt;的ArrayList&LT;长&GT;&GT;所以每次我添加一个导入我都会在这个东西上添加ID#34;我不喜欢。 (arraylist的araylist)

每个数组的长数将在第一个位置上有#34; Bo id标题&#34;,每次Bo导入时,新的Id在其列表中添加,AND每个其他Bo导入Bo(一个makin the import)。

因此,如果我的用户试图从B1制作B9,该方法将检测到,B1将被添加到自己的列表中并且不允许。

实施起来非常简单。 (让我们使用java,不,我使用.net,自己没有启动这个项目)

示例   {{}}

从B2进口B1:   {的 {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 }}

从B10进口B3:   {{B1,B2,B3,B4,B9,的 B10 },{B2,B4,B9},{B4,B9}的 {B3,B10} } < / p>

每个数组的长数将在第一个位置上有#34; Bo id标题&#34;,每次Bo导入时,新的Id在其列表中添加,AND每个其他Bo导入Bo(一个makin the import)。

因此,如果我的用户试图从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可以非常快地取决于用户)。 标题是速度。

1 个答案:

答案 0 :(得分:0)

如果我正确理解了这个问题,那么检查'循环'实际上是图表中循环检测的一个例子。换句话说,如果每个“导入”都被建模为有向图边,那么您就是在尝试检测一个循环。

如果这是正确的,那么这是一个很好理解的问题。我建议将导入建模为直接节点参考,然后使用其中一种标准算法来检测周期,请参阅Cycle Detection