使用手册 - 寻路启发器功能:修订间差异

来自MDCS wiki
跳到导航 跳到搜索
无编辑摘要
 
(未显示同一用户的2个中间版本)
第45行: 第45行:
这个示例展示了一个简单的启发器,它根据车辆和轨道的特定字段来决定是否允许车辆通过某条路径。
这个示例展示了一个简单的启发器,它根据车辆和轨道的特定字段来决定是否允许车辆通过某条路径。


== 4. 启发器类型 ==
== 4. 启发器类型和默认值 ==
启发器可以有不同的类型,通过 <code>HeuristicDef</code> 属性的 <code>role</code> 参数指定:
启发器可以有不同的类型,通过 <code>HeuristicDef</code> 属性的 <code>role</code> 参数指定:


第55行: 第55行:
</syntaxhighlight>
</syntaxhighlight>


* <code>PreSelect</code>:在考虑新节点之前调用
* <code>PreSelect</code>:在考虑新节点之前调用(默认值)
* <code>Price</code>:用于计算路径成本
* <code>Price</code>:用于计算路径成本
* <code>PerRoute</code>:验证整个路径
* <code>PerRoute</code>:验证整个路径
* <code>PostSelect</code>:在其他启发式方法之后进行最终筛选
* <code>PostSelect</code>:在其他启发式方法之后进行最终筛选


== 5. 访问上下文信息 ==
默认情况下,如果不指定 <code>role</code>,启发器将被视为 <code>PreSelect</code> 类型。
 
== 5. FindRoute 算法工作原理 ==
FindRoute 方法使用了一种启发式搜索算法,类似于 A* 算法。它的主要步骤如下:
 
# 初始化搜索状态,将起点加入优先队列。
# 从优先队列中取出最优的搜索状态。
# 对当前状态的所有相邻节点进行扩展。
# 应用各种启发器来过滤和评估新的搜索状态。
# 将有效的新状态加入优先队列。
# 重复步骤 2-5,直到找到目标或达到搜索限制。
 
在这个过程中:
* <code>priority</code> 用于确定搜索状态在优先队列中的顺序。优先级越高(数值越小),状态越优先被处理。
* <code>price</code> 表示从起点到当前节点的累计成本。当优先级相同时,价格较低的状态会被优先处理。
 
== 6. 内置启发器及其用途 ==
系统提供了几个内置的启发器,它们位于 <code>BasicHeuristics</code> 和 <code>Cut</code> 类中:
 
=== BasicHeuristics ===
# <code>Routing</code>:处理路由规则,确保车辆遵循预定义的路径。[[使用手册-routing字段:设置车辆必经点(必不经点)逻辑]]
# <code>BasicPrice</code>:计算基本路径成本,基于节点间的距离。
# <code>UnavailableDetour</code>:降低无法锁定的节点的优先级,鼓励寻找可用路径。
# <code>ForbidRouteOnDestination</code>:处理目的地冲突,避免多辆车同时前往同一目的地。
 
=== Cut ===
# <code>CutOp</code>:实现了一种剪枝策略,通过限制对每个节点的访问次数来提高搜索效率。
 
这些内置启发器共同工作,以确保路径规划的效率、安全性和可行性。
 
== 7. 访问上下文信息 ==
在启发器方法中,你可以访问 <code>SegmentPlan.SearchStat</code> 对象,它包含了当前搜索状态的信息:
在启发器方法中,你可以访问 <code>SegmentPlan.SearchStat</code> 对象,它包含了当前搜索状态的信息:


第67行: 第97行:
* <code>stat.previousTrack</code>:前一个轨道
* <code>stat.previousTrack</code>:前一个轨道
* <code>stat.sequence</code>:已访问的站点序列
* <code>stat.sequence</code>:已访问的站点序列
* <code>stat.price</code>:当前路径的累计成本
* <code>stat.priority</code>:当前状态的优先级
* <code>plan.usingCar</code>:当前使用的车辆
* <code>plan.usingCar</code>:当前使用的车辆


== 6. 高级用法 ==
== 8. 高级用法 ==


=== 6.1 车辆特定启发器 ===
=== 8.1 车辆特定启发器 ===
你可以创建只适用于特定类型车辆的启发器:
你可以创建只适用于特定类型车辆的启发器:


第82行: 第114行:
</syntaxhighlight>
</syntaxhighlight>


=== 6.2 定价启发器 ===
=== 8.2 定价启发器 ===
定价启发器用于调整路径的成本或优先级:
定价启发器用于调整路径的成本或优先级:


第97行: 第129行:
</syntaxhighlight>
</syntaxhighlight>


=== 6.3 初始化逻辑 ===
=== 8.3 初始化逻辑 ===
如果你的启发器需要一些初始化逻辑,可以重写 <code>initHeuristics</code> 方法:
如果你的启发器需要一些初始化逻辑,可以重写 <code>initHeuristics</code> 方法:


第107行: 第139行:
</syntaxhighlight>
</syntaxhighlight>


== 7. 最佳实践 ==
== 9. 最佳实践 ==
# 保持启发器简单和高效,因为它们会被频繁调用。
# 保持启发器简单和高效,因为它们会被频繁调用。
# 利用不同类型的启发器(PreSelect、Price、PerRoute、PostSelect)来优化搜索过程的不同阶段。
# 利用不同类型的启发器(PreSelect、Price、PerRoute、PostSelect)来优化搜索过程的不同阶段。
第113行: 第145行:
# 充分利用 <code>SegmentPlan.SearchStat</code> 对象提供的上下文信息。
# 充分利用 <code>SegmentPlan.SearchStat</code> 对象提供的上下文信息。
# 在复杂的启发器中考虑性能优化,例如缓存计算结果。
# 在复杂的启发器中考虑性能优化,例如缓存计算结果。
# 合理使用 <code>priority</code> 和 <code>price</code> 来引导搜索算法找到最优路径。


通过正确使用启发器,你可以极大地提高路径规划的效率和准确性,同时满足复杂的业务需求。
通过正确使用启发器,你可以极大地提高路径规划的效率和准确性,同时满足复杂的业务需求。

2024年10月9日 (三) 17:47的最新版本

使用手册 - 寻路启发器功能

1. 寻路启发器作用

在实际现场业务中,我们往往需要对"哪种车可以走哪条路"进行限定,或者自定义寻路的规则。寻路启发器允许我们定义这些自定义规则,以优化路径搜索过程,提高效率并满足特定的业务需求。

2. 寻路启发器工作原理

寻路启发器在路径搜索过程中起着关键作用。它们被用于:

  1. 预选(PreSelect):在考虑一个新的路径节点之前进行初步筛选。
  2. 定价(Price):为路径分配成本或优先级。
  3. 路径验证(PerRoute):验证整个路径是否有效。
  4. 后选(PostSelect):在其他启发式方法之后进行最终筛选。

系统会在搜索过程中的不同阶段调用这些启发器,以指导搜索算法做出更智能的决策。

3. 如何定义一个启发器

要定义一个启发器,请按照以下步骤操作:

  1. 创建一个继承自 HeuristicsContainer 的类。
  2. 在类中定义一个或多个方法,并使用 [HeuristicDef] 属性标记它们。
  3. 根据需要实现启发式逻辑。

基本示例

public class BYDBcHeuristics : HeuristicsContainer
{
    [HeuristicDef]
    public bool BYDCarShouldGo(SegmentPlan.SearchStat stat)
    {
        if (plan.usingCar.fields.ContainsKey("A"))
        {
            if (stat.previousTrack.fields.ContainsKey("noAllowA")) return false;
            return true;
        }
        if (plan.usingCar.fields.ContainsKey("BC"))
        {
            if (stat.previousTrack.fields.ContainsKey("noAllowBC")) return false;
            return true;
        }
        return true;
    }
}

这个示例展示了一个简单的启发器,它根据车辆和轨道的特定字段来决定是否允许车辆通过某条路径。

4. 启发器类型和默认值

启发器可以有不同的类型,通过 HeuristicDef 属性的 role 参数指定:

[HeuristicDef(role = HeuristicDef.HType.PreSelect)]
[HeuristicDef(role = HeuristicDef.HType.Price)]
[HeuristicDef(role = HeuristicDef.HType.PerRoute)]
[HeuristicDef(role = HeuristicDef.HType.PostSelect)]
  • PreSelect:在考虑新节点之前调用(默认值)
  • Price:用于计算路径成本
  • PerRoute:验证整个路径
  • PostSelect:在其他启发式方法之后进行最终筛选

默认情况下,如果不指定 role,启发器将被视为 PreSelect 类型。

5. FindRoute 算法工作原理

FindRoute 方法使用了一种启发式搜索算法,类似于 A* 算法。它的主要步骤如下:

  1. 初始化搜索状态,将起点加入优先队列。
  2. 从优先队列中取出最优的搜索状态。
  3. 对当前状态的所有相邻节点进行扩展。
  4. 应用各种启发器来过滤和评估新的搜索状态。
  5. 将有效的新状态加入优先队列。
  6. 重复步骤 2-5,直到找到目标或达到搜索限制。

在这个过程中:

  • priority 用于确定搜索状态在优先队列中的顺序。优先级越高(数值越小),状态越优先被处理。
  • price 表示从起点到当前节点的累计成本。当优先级相同时,价格较低的状态会被优先处理。

6. 内置启发器及其用途

系统提供了几个内置的启发器,它们位于 BasicHeuristicsCut 类中:

BasicHeuristics

  1. Routing:处理路由规则,确保车辆遵循预定义的路径。使用手册-routing字段:设置车辆必经点(必不经点)逻辑
  2. BasicPrice:计算基本路径成本,基于节点间的距离。
  3. UnavailableDetour:降低无法锁定的节点的优先级,鼓励寻找可用路径。
  4. ForbidRouteOnDestination:处理目的地冲突,避免多辆车同时前往同一目的地。

Cut

  1. CutOp:实现了一种剪枝策略,通过限制对每个节点的访问次数来提高搜索效率。

这些内置启发器共同工作,以确保路径规划的效率、安全性和可行性。

7. 访问上下文信息

在启发器方法中,你可以访问 SegmentPlan.SearchStat 对象,它包含了当前搜索状态的信息:

  • stat.CurrentSite:当前站点
  • stat.previous:前一个搜索状态
  • stat.previousTrack:前一个轨道
  • stat.sequence:已访问的站点序列
  • stat.price:当前路径的累计成本
  • stat.priority:当前状态的优先级
  • plan.usingCar:当前使用的车辆

8. 高级用法

8.1 车辆特定启发器

你可以创建只适用于特定类型车辆的启发器:

[HeuristicDef(carTypes = new[] { typeof(ElectricCar) })]
public bool ElectricCarHeuristic(SegmentPlan.SearchStat stat)
{
    // 只对电动车应用的逻辑
}

8.2 定价启发器

定价启发器用于调整路径的成本或优先级:

[HeuristicDef(role = HeuristicDef.HType.Price)]
public void AdjustPrice(SegmentPlan.SearchStat stat)
{
    // 根据某些条件调整价格
    if (SomeCondition)
    {
        stat.price += 10;
    }
}

8.3 初始化逻辑

如果你的启发器需要一些初始化逻辑,可以重写 initHeuristics 方法:

public override void initHeuristics()
{
    // 执行一些初始化逻辑
}

9. 最佳实践

  1. 保持启发器简单和高效,因为它们会被频繁调用。
  2. 利用不同类型的启发器(PreSelect、Price、PerRoute、PostSelect)来优化搜索过程的不同阶段。
  3. 使用车辆特定的启发器来处理不同类型车辆的特殊需求。
  4. 充分利用 SegmentPlan.SearchStat 对象提供的上下文信息。
  5. 在复杂的启发器中考虑性能优化,例如缓存计算结果。
  6. 合理使用 priorityprice 来引导搜索算法找到最优路径。

通过正确使用启发器,你可以极大地提高路径规划的效率和准确性,同时满足复杂的业务需求。