2

我很难理解如何在我尝试开发的基于代理的模型中结合基于规则的决策制定方法。

代理的界面非常简单。

public interface IAgent
{
   public string ID { get; }

   public Action Percept(IPercept percept);
}

为了这个例子,让我们假设代理代表车辆,它们在一个大型仓库内穿过道路,以装载和卸载他们的货物。他们的路线(道路序列,从起点到代理的目的地)由另一个代理,主管分配。车辆代理的目标是遍历其指定的路线,卸载货物,装载新的,接收主管指定的另一条路线并重复该过程。

车辆还必须意识到潜在的碰撞,例如在交叉点,并根据某些规则给予优先权(例如,载有最重货物的车辆具有优先权)。

据我了解,这是我要构建的代理的内部结构:

在此处输入图像描述

所以车辆代理可以是这样的:

public class Vehicle : IAgent
{
  public VehicleStateUpdater { get; set; }

  public RuleSet RuleSet { get; set; }

  public VehicleState State { get; set; }

  public Action Percept(IPercept percept)
  {
    VehicleStateUpdater.UpdateState(VehicleState, percept);
    Rule validRule = RuleSet.Match(VehicleState);
    VehicleStateUpdater.UpdateState(VehicleState, validRule);
    Action nextAction = validRule.GetAction();
    return nextAction;
  }
}

对于 Vehicle 代理的内部状态,我正在考虑类似:

public class VehicleState
{
  public Route Route { get; set; }

  public Cargo Cargo { get; set; }

  public Location CurrentLocation { get; set; }
}

对于此示例,必须为车辆代理实施 3 条规则。

  1. 如果另一辆车在代理附近(例如小于 50 米),则货物最重的那辆优先,其他代理必须保持其位置。
  2. 当代理到达目的地时,他们卸下货物,装载新货物并等待主管分配新路线。
  3. 在任何给定时刻,无论出于何种原因,主管都可能发送命令,接收车辆必须遵守该命令(保持位置或继续)。

VehicleStateUpdater 必须考虑代理的当前状态、接收到的感知类型并相应地更改状态。因此,为了使状态反映例如主管收到了一条命令,可以按如下方式对其进行修改:

public class VehicleState
{
  public Route Route { get; set; }

  public Cargo Cargo { get; set; }

  public Location CurrentLocation { get; set; }

  // Additional Property
  public RadioCommand ActiveCommand { get; set; }
}

其中 RadioCommand 可以是值为 None、Hold、Continue 的枚举。

但是现在我还必须在代理状态下注册,如果另一辆车正在接近。所以我必须向 VehicleState 添加另一个属性。

public class VehicleState
{
  public Route Route { get; set; }

  public Cargo Cargo { get; set; }

  public Location CurrentLocation { get; set; }

  public RadioCommand ActiveCommand { get; set; }

  // Additional properties
  public bool IsAnotherVehicleApproaching { get; set; }

  public Location ApproachingVehicleLocation { get; set; }
}

这就是我很难理解如何进行的地方,而且我觉得我并没有真正遵循正确的方法。首先,我不确定如何使 VehicleState 类更加模块化和可扩展。其次,我不确定如何实现定义决策过程的基于规则的部分。我应该创建互斥规则(这意味着每个可能的状态必须对应不超过一个规则)?是否有一种设计方法可以让我添加额外的规则,而不必来回切换 VehicleState 类并添加/修改属性,以确保代理的内部状态可以处理每种可能的 Percept 类型?

我已经看过《人工智能:现代方法》教材和其他资源中演示的示例,但是当必须设计更复杂的模型时,可用示例太简单了,我无法“掌握”相关概念。

如果有人能指出关于基于规则部分的实施的正确方向,我将不胜感激。

我正在用 C# 编写,但据我所知,它与我试图解决的更广泛的问题并不真正相关。

更新:

我尝试合并的规则示例:

public class HoldPositionCommandRule : IAgentRule<VehicleState>
{
    public int Priority { get; } = 0;

    public bool ConcludesTurn { get; } = false;


    public void Fire(IAgent agent, VehicleState state, IActionScheduler actionScheduler)
    {
        state.Navigator.IsMoving = false;
        //Use action scheduler to schedule subsequent actions...
    }

    public bool IsValid(VehicleState state)
    {
        bool isValid = state.RadioCommandHandler.HasBeenOrderedToHoldPosition;
        return isValid;
    }
}

我也尝试实施的代理决策者示例。

public void Execute(IAgentMessage message,
                    IActionScheduler actionScheduler)
{
    _agentStateUpdater.Update(_state, message);
    Option<IAgentRule<TState>> validRule = _ruleMatcher.Match(_state);
    validRule.MatchSome(rule => rule.Fire(this, _state, actionScheduler));
}
4

1 回答 1

2

我认为您的问题包含两个主要子问题:

  • 建模灵活性,特别是如何更容易地向系统添加属性和规则。
  • 如何提出正确的规则集以及如何组织它们以使代理正常工作。

所以让我们去看看他们每个人。

建模灵活性

我觉得你现在拥有的其实还不错。让我解释一下为什么。

您表达了对“一种设计方法允许我添加其他规则而不必来回切换 VehicleState 类和添加/修改属性”的担忧。

我认为答案是“不”,除非你遵循完全不同的路径,让智能体自主学习规则和属性(如深度强化学习),这会带来一系列困难。

如果您要按照问题中的描述手动编码代理知识,那么您将如何避免在添加新规则时引入新属性的需要?您当然可以尝试预测您将需要的所有属性,并且不允许自己编写需要新属性的规则,但新规则的本质是带来问题的新方面,这通常需要新属性。这与需要多次迭代和更改的软件工程不同。

基于规则的建模

有两种编写规则的方式:命令式和声明式。

  • 在命令式风格中,您编写采取行动所需的条件。当两者都适用时,您还必须注意选择一个操作而不是另一个操作(可能使用优先系统)。因此,您可以制定一条沿路线行驶的规则,并制定一条在优先级较高的车辆接近时停下来的规则。这似乎是您目前正在追求的方法。

  • 在声明式风格中,您声明环境的规则是什么、操作如何影响环境以及您关心什么(将实用程序分配给特定状态或子状态),并让系统处理所有这些以计算最佳操作你。所以在这里你声明决定移动如何影响你的位置,你声明碰撞是如何发生的,你声明到达你路线的尽头是好的,碰撞是坏的。请注意,在这里您没有做出决定的规则;系统使用规则来确定在特定情况下具有最大价值的动作。

理解命令式和声明式风格之间区别的一种直观方法是考虑编写一个下棋的代理。以命令式的方式,程序员对国际象棋的规则进行编码,还包括如何下棋、如何开局、如何选择最佳走法等等。也就是说,系统会体现出程序员的棋艺。在声明式风格中,程序员只需对国际象棋规则进行编码,以及系统如何自动探索这些规则并确定最佳棋步。在这种情况下,程序员不需要知道如何下好国际象棋,程序就可以真正下一个像样的国际象棋游戏。

命令式风格实现起来更简单,但灵活性较差,并且随着系统复杂性的增加会变得非常混乱。您必须开始考虑各种场景,例如当三辆车相遇时该怎么办。在国际象棋的例子中,想象一下如果我们稍微改变一个国际象棋规则;整个系统需要审查!在某种程度上,命令式系统中几乎没有“人工智能”和“推理”,因为是程序员提前进行所有推理,提出所有解决方案并对其进行编码。它只是一个常规程序,而不是人工智能程序。这似乎是你所说的那种困难。

声明式风格更加优雅和可扩展。您无需弄清楚如何确定最佳操作;系统会为您完成。在国际象棋示例中,您可以轻松地更改代码中的一条国际象棋规则,系统将使用新规则在更改后的游戏中找到最佳着法。但是,它需要一个推理引擎,该软件知道如何接受大量规则和实用程序并决定哪个是最佳操作。这样的推理引擎就是系统中的“人工智能”。它会自动考虑所有可能的场景(不一定要一一考虑,因为它通常会采用考虑类的更智能的技术场景)并确定每个场景中的最佳操作。但是,推理引擎实现起来很复杂,或者,如果您使用现有的推理引擎,它可能非常有限,因为这些通常是研究包。我相信,当涉及到使用声明性方法的实际实际应用程序时,人们几乎会为他们的特定需求编写一个定制的系统。

我发现了一些类似的研究开源项目(见下文);这将使您了解可用的内容。如您所见,这些都是研究项目,范围相对有限。

毕竟,如何进行?我不知道你的具体目标是什么。如果您正在开发一个玩具问题来练习,那么您当前的命令式样式系统可能就足够了。如果您想了解声明式风格,深入阅读 AIMA 教科书会很好。作者还维护了一个开源存储库,其中包含书中某些算法的实现

https://www.jmlr.org/papers/v18/17-156.html

https://github.com/douthwja01/OpenMAS

https://smartgrid.ieee.org/newsletters/may-2021/multi-agent-opendss-an-open-source-and-scalable-distribution-grid-platform

于 2021-07-24T21:04:21.730 回答