You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Timefold约束中实现基于Visit、Vehicle及对应访问量三元组的过滤逻辑?

如何在Timefold约束中实现基于Visit、Vehicle及对应访问量三元组的过滤逻辑?

嘿,我完全懂你的需求——你想在约束逻辑里同时拿到单个Visit实例、它对应的Vehicle,以及该Vehicle的总访问次数,然后把这三个元素凑成三元组来做过滤判断对吧?其实这个实现思路很清晰,咱们可以通过两种常见的方式来搞定,我给你一步步拆解:

方法一:先统计访问量,再关联原始Visit流

这个方法的核心是先单独统计每个Vehicle的总访问数,再把这个统计结果和原始的Visit流关联起来,这样每个Visit就能带上对应的Vehicle和总访问数,形成你要的三元组:

def too_many_visits_per_visit(factory: ConstraintFactory) -> Constraint:
    # 第一步:先统计每个Vehicle的总访问次数,得到(Vehicle, 访问数)的流
    vehicle_visit_count_stream = factory.for_each(Visit)\
        .group_by(lambda visit: visit.vehicle, ConstraintCollectors.count())
    
    # 第二步:把原始Visit和统计结果关联,拿到(Visit, Vehicle, 访问数)三元组
    return factory.for_each(Visit)\
        # 关联条件:Visit的Vehicle和统计流里的Vehicle一致
        .join(vehicle_visit_count_stream, 
              lambda visit, vehicle_count_pair: visit.vehicle == vehicle_count_pair[0])\
        # 现在可以对三元组做任意过滤了,比如结合Visit的属性、Vehicle、访问数
        .filter(lambda visit, vehicle_count_pair: 
                # 解构得到三个元素
                vehicle = vehicle_count_pair[0],
                visit_count = vehicle_count_pair[1],
                # 这里写你的自定义过滤逻辑,比如:访问数超10,且该Visit是紧急任务
                visit_count > 10 and visit.is_emergency)\
        # 按需求设置惩罚分数
        .penalize(HardSoftScore.ONE_HARD,
                  lambda visit, vehicle_count_pair: vehicle_count_pair[1] - 10)\
        .as_constraint("too_many_visits_per_visit")

方法二:分组后展开列表,直接生成三元组

另一种更直观的方式是,先把同一个Vehicle下的所有Visit收集成列表,然后把列表展开,同时带上Vehicle和列表长度(也就是总访问数),这样也能得到目标三元组:

def too_many_visits_per_visit(factory: ConstraintFactory) -> Constraint:
    return factory.for_each(Visit)\
        # 按Vehicle分组,同时收集该组下的所有Visit
        .group_by(lambda visit: visit.vehicle, 
                  ConstraintCollectors.to_list(lambda visit: visit))\
        # 把每个组展开,生成(Visit, Vehicle, 总访问数)的三元组
        .flat_map(lambda vehicle, visit_list: 
                  [(visit, vehicle, len(visit_list)) for visit in visit_list])\
        # 现在直接对三元组做过滤
        .filter(lambda visit_vehicle_count: 
                # 解构三元组
                visit, vehicle, visit_count = visit_vehicle_count,
                # 自定义过滤逻辑示例:访问数超10,且Vehicle属于特定区域
                visit_count > 10 and vehicle.region == "North")\
        .penalize(HardSoftScore.ONE_HARD,
                  lambda visit_vehicle_count: visit_vehicle_count[2] - 10)\
        .as_constraint("too_many_visits_per_visit")

为什么这个思路能行?

你之前觉得应该简单但没头绪,主要是因为直接group_by后得到的是Vehicle和访问数的二元组,丢失了原始的Visit实例。而上面两种方法都是通过关联原始Visit流或者展开分组后的Visit列表,把单个Visit重新和对应的Vehicle、全局访问数绑定起来,这样就可以完全按照你的需求对三元组做任意过滤了。

备注:内容来源于stack exchange,提问作者Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:04:33