代码之家  ›  专栏  ›  技术社区  ›  Jason Coyne

同时进行有效的前臂儿童评估

  •  7
  • Jason Coyne  · 技术社区  · 14 年前

    我有一个对象列表,每个对象上都有bool shouldrun()方法。

    我目前正在迭代对象列表,并检查每个对象的shouldrun(),并在第一个返回true的对象上调用run()。

    foreach (child in Children)
    {
       if (child.ShouldRun())
       {
          child.Run();
          break;
        }
     }
    

    我想并行进行这项工作,因为评估应该花费相当多的时间,并且让集合中的稍后元素尽早开始评估是有利的。

    但是,我想不出一种方法可以满足这些条件:

    1只运行一个项目

    2如果早期项为真或尚未完成评估,则不要运行后期项

    3如果所有“早期”项都返回了false,中间项返回了true,则不要等待后续项完成评估,因为您知道它不能覆盖任何早期项。

    I thought of doing a parallel "where" linq query to retrieve all the items that shouldRun() and then sorting, but this will violate condition #3

    思想?

    背景信息:

    该系统是一个通用的机器人AI系统。

    一些更高优先级的任务可以由立即知道的传感器变量触发,例如:我摔倒了,修复它!

    其他任务可能是计算密集型的(从相机进行图像识别,并接近可见目标)

    其他任务可能是数据库或远程驱动的(从数据库中查找可能的目标位置列表,然后导航到该列表,查看是否可以进入其中一个目标的可见范围)

    有些任务本身有子任务,基本上是在任务的一个子集上递归地启动这个过程,而孙子任务将通过链向上传递。

    4 回复  |  直到 14 年前
        1
  •  3
  •   Stephen Cleary    14 年前

    我不是一个天才,但这个简单的答案就够了吗?

    var childToRun = Children.AsParallel().AsOrdered()
        .Where(x => x.ShouldRun()).FirstOrDefault();
    childToRun.Run();  
    
        2
  •  0
  •   FrantiÅ¡ek Žiačik    14 年前

    Just a concept of way I would try to do it.

    全部运行 ShouldRun() 是并行的。将结果与项目的项目和索引一起放入有序列表(例如,第三个项目的shouldrun()以false结尾,列表将包含如下内容:2、false、item)。

    在另一个线程中,保持当前索引从0开始,并定期检查排序列表。如果列表上的下一个索引等于current,则处理结果并前进当前索引。

        3
  •  0
  •   tzaman    14 年前

    您应该能够对附加的索引进行并行选择,然后根据索引对结果进行排序,并选择返回的第一个索引。 true . 我在这台机器上没有IDE,所以这是未经测试的,但类似于:

    var runnables = Children.AsParallel()
                            .Select(child, index => 
                                    new { 
                                            Index = index, 
                                            ShouldRun = child.ShouldRun(),
                                            Child = child 
                                        })
                            .ToList(); //force evaluation
    var firstRunner = runnables.OrderBy(r => r.Index)
                               .First(r => r.ShouldRun) //assuming at least one
                                       //else use FirstOrDefault and null-check
                               .Child;
    firstRunner.Run();
    

    编辑:更好地查询第一个运行程序-

    var firstRunner = runnables.Where(r => r.ShouldRun) // less stuff to sort later
                               .OrderBy(r => r.Index)
                               .First(); // no need for predicate here anymore
    

    Edt2:不过,这并不能满足你的条件3。

        4
  •  0
  •   Ira Baxter    14 年前

    I'm puzzled as to why you have a "ShouldRun" flag on each child, rather than having earlier placed each child that you would mark as "ShouldRun" into a "RunThese" set.

    然后,你只需询问运行这些设置的大小是否为零,如果不是0,则将它们全部运行。

    [当然,如果你要运行它们,为什么还要标记/设置联合它们?你可以在发现应该运行它们时启动它们。如果您认为should run逻辑很昂贵,那么在您有孩子的时候就把它分给您,以决定是否应该管理孩子。]