人群仿真案例研究

1. 案例背景

在人群仿真领域,AnyLogic 是一个功能强大的工具,可以用于模拟各种复杂的人群行为和场景。本节将通过一个具体的案例研究,展示如何在 AnyLogic 中进行人群仿真。我们将模拟一个机场的旅客流动,探讨如何设置仿真模型、定义人群行为,并分析仿真结果。

1.1 机场旅客流动仿真背景

机场是一个高度复杂的环境,旅客的行为模式多种多样,包括安检、登机、购物等。通过人群仿真,我们可以更好地理解旅客在不同时间段内的流动情况,优化机场的资源配置,提高旅客的满意度。本案例将模拟一个中型机场的旅客流动,重点探讨以下几个方面:

  • 旅客到达模式

  • 安检过程

  • 登机口排队

  • 购物行为

2. 模型设置

2.1 创建新的仿真项目

  1. 打开 AnyLogic 软件。

  2. 选择“New Project”。

  3. 在“New Project”对话框中,选择“Agent Based Modeling”模板,点击“Next”。

  4. 输入项目名称,例如“Airport Passenger Flow Simulation”,点击“Finish”。

2.2 定义仿真环境

  1. 创建机场布局

    • 在主窗口中,使用“Drawing”工具栏中的图形工具(如矩形、圆形、线条等)绘制机场的平面图。

    • 包括安检口、登机口、商店、休息区等关键区域。

  2. 设置仿真参数

    • 在“Simulation”选项卡中,设置仿真时间(例如 24 小时)。

    • 设置仿真步长(例如 1 分钟)。

2.3 定义人群代理

  1. 创建旅客代理

    • 在“Agents”选项卡中,创建一个新的代理类型,命名为“Passenger”。

    • 在“Passenger”代理中,定义旅客的各种属性,例如:

      • int passengerId:旅客的唯一标识。

      • double arrivalTime:旅客到达机场的时间。

      • int destinationGate:旅客的目的地登机口编号。

      • boolean hasShopped:旅客是否已经购物。

  2. 定义旅客行为

    • 使用“Statechart”工具定义旅客的各个行为状态,例如:

      • Arrival:旅客到达机场。

      • SecurityCheck:旅客进行安检。

      • GoToGate:旅客前往登机口。

      • Shopping:旅客购物。

      • Boarding:旅客登机。


// 定义旅客代理类

public class Passenger extends Agent {

    // 旅客属性

    private int passengerId;

    private double arrivalTime;

    private int destinationGate;

    private boolean hasShopped;



    // 设置旅客属性

    public void setPassengerId(int passengerId) {

        this.passengerId = passengerId;

    }



    public void setArrivalTime(double arrivalTime) {

        this.arrivalTime = arrivalTime;

    }



    public void setDestinationGate(int destinationGate) {

        this.destinationGate = destinationGate;

    }



    public void setHasShopped(boolean hasShopped) {

        this.hasShopped = hasShopped;

    }



    // 获取旅客属性

    public int getPassengerId() {

        return passengerId;

    }



    public double getArrivalTime() {

        return arrivalTime;

    }



    public int getDestinationGate() {

        return destinationGate;

    }



    public boolean hasShopped() {

        return hasShopped;

    }



    // 定义旅客的行为状态

    @State

    public class Arrival extends State<Passenger> {

        public void onEntry() {

            // 设置到达时间

            setArrivalTime(time());

            // 进入安检状态

            transitionTo(new SecurityCheck());

        }

    }



    @State

    public class SecurityCheck extends State<Passenger> {

        public void onEntry() {

            // 模拟安检过程

            hold(10.0); // 假设安检需要 10 分钟

            // 完成安检后,随机决定是否购物

            if (randomTrue(0.3)) {

                transitionTo(new Shopping());

            } else {

                transitionTo(new GoToGate());

            }

        }

    }



    @State

    public class Shopping extends State<Passenger> {

        public void onEntry() {

            // 模拟购物过程

            hold(15.0); // 假设购物需要 15 分钟

            setHasShopped(true);

            // 购物完成后前往登机口

            transitionTo(new GoToGate());

        }

    }



    @State

    public class GoToGate extends State<Passenger> {

        public void onEntry() {

            // 模拟前往登机口的过程

            hold(5.0); // 假设前往登机口需要 5 分钟

            // 到达登机口

            transitionTo(new Boarding());

        }

    }



    @State

    public class Boarding extends State<Passenger> {

        public void onEntry() {

            // 模拟登机过程

            hold(10.0); // 假设登机需要 10 分钟

            // 登机完成后,旅客离开系统

            exit();

        }

    }

}

2.4 创建仿真环境

  1. 定义机场布局

    • 在主窗口中,使用“Drawing”工具栏绘制机场的平面图。

    • 创建矩形代表安检口、登机口、商店等区域。

  2. 设置人流路径

    • 使用“Path”工具创建旅客的行走路径。

    • 确保路径连接所有关键区域,例如从安检口到登机口、从安检口到商店等。


// 定义机场环境类

public class Airport extends Environment {

    // 创建安检口、登机口、商店等区域

    private Rectangle securityCheckArea;

    private Rectangle boardingGateArea;

    private Rectangle shopArea;



    // 创建人流路径

    private Path pathToSecurityCheck;

    private Path pathToBoardingGate;

    private Path pathToShop;



    public void setup() {

        // 设置安检口区域

        securityCheckArea = new Rectangle(0, 0, 100, 50);

        securityCheckArea.setFill(Color.LIGHTGRAY);

        add(securityCheckArea);



        // 设置登机口区域

        boardingGateArea = new Rectangle(300, 0, 100, 50);

        boardingGateArea.setFill(Color.LIGHTBLUE);

        add(boardingGateArea);



        // 设置商店区域

        shopArea = new Rectangle(150, 0, 100, 50);

        shopArea.setFill(Color.LIGHTGREEN);

        add(shopArea);



        // 设置人流路径

        pathToSecurityCheck = new Path(new Point(0, 50), new Point(100, 50));

        add(pathToSecurityCheck);



        pathToBoardingGate = new Path(new Point(150, 50), new Point(300, 50));

        add(pathToBoardingGate);



        pathToShop = new Path(new Point(100, 50), new Point(150, 50));

        add(pathToShop);

    }

}

3. 仿真逻辑

3.1 旅客到达模式

  1. 设置旅客到达率

    • 使用“Source”工具设置旅客的到达模式。

    • 例如,每 5 分钟到达一个旅客。

  2. 生成旅客

    • 在“Source”中设置生成旅客的代码,初始化旅客的属性。

// 旅客到达源

public class PassengerSource extends Source<Passenger> {

    public PassengerSource() {

        // 设置每 5 分钟到达一个旅客

        setInterArrivalTime(5.0);

    }



    @Override

    protected Passenger create() {

        // 创建新的旅客对象

        Passenger passenger = new Passenger();

        // 设置旅客的唯一标识

        passenger.setPassengerId(getNextAgentId());

        // 随机选择目的地登机口

        passenger.setDestinationGate(randomInt(1, 5));

        return passenger;

    }

}

3.2 安检过程

  1. 设置安检队列

    • 使用“Queue”工具设置安检队列。

    • 设置队列的最大长度和等待时间。

  2. 定义安检过程

    • 使用“Service”工具定义安检过程。

    • 设置安检所需的时间和资源。


// 安检队列

public class SecurityQueue extends Queue<Passenger> {

    public SecurityQueue() {

        // 设置队列的最大长度

        setCapacity(20);

        // 设置等待时间

        setWaitTime(10.0);

    }

}



// 安检服务

public class SecurityService extends Service<Passenger> {

    public SecurityService() {

        // 设置安检所需的时间

        setProcessingTime(10.0);

        // 设置安检所需的资源数量

        setResourceCapacity(3);

    }

}

3.3 登机口排队

  1. 设置登机口队列

    • 使用“Queue”工具设置登机口队列。

    • 设置队列的最大长度和等待时间。

  2. 定义登机过程

    • 使用“Service”工具定义登机过程。

    • 设置登机所需的时间和资源。


// 登机口队列

public class BoardingQueue extends Queue<Passenger> {

    public BoardingQueue() {

        // 设置队列的最大长度

        setCapacity(50);

        // 设置等待时间

        setWaitTime(10.0);

    }

}



// 登机服务

public class BoardingService extends Service<Passenger> {

    public BoardingService() {

        // 设置登机所需的时间

        setProcessingTime(10.0);

        // 设置登机所需的资源数量

        setResourceCapacity(5);

    }

}

3.4 购物行为

  1. 设置商店队列

    • 使用“Queue”工具设置商店队列。

    • 设置队列的最大长度和等待时间。

  2. 定义购物过程

    • 使用“Service”工具定义购物过程。

    • 设置购物所需的时间和资源。


// 商店队列

public class ShopQueue extends Queue<Passenger> {

    public ShopQueue() {

        // 设置队列的最大长度

        setCapacity(30);

        // 设置等待时间

        setWaitTime(15.0);

    }

}



// 购物服务

public class ShopService extends Service<Passenger> {

    public ShopService() {

        // 设置购物所需的时间

        setProcessingTime(15.0);

        // 设置购物所需的资源数量

        setResourceCapacity(5);

    }

}

4. 数据收集与分析

4.1 收集仿真数据

  1. 设置数据收集器

    • 使用“Data Collector”工具设置数据收集器,收集旅客的到达时间、安检时间、购物时间、登机时间等数据。
  2. 定义数据收集指标

    • 例如,收集每个旅客的总等待时间、每个安检口的通过率、每个登机口的排队长度等。

// 数据收集器

public class PassengerDataCollector extends DataCollector<Passenger> {

    public PassengerDataCollector() {

        // 设置数据收集的变量

        addVariable("arrivalTime", "double", "agent.getArrivalTime()");

        addVariable("securityCheckTime", "double", "agent.getArrivalTime() + getSimulation().getEngine().getProcessStarttime(agent)");

        addVariable("shoppingTime", "double", "agent.hasShopped() ? agent.getArrivalTime() + getSimulation().getEngine().getProcessStarttime(agent) : 0");

        addVariable("boardingTime", "double", "agent.getArrivalTime() + getSimulation().getEngine().getProcessStarttime(agent) + getSimulation().getEngine().getProcessDuration(agent)");

    }

}

4.2 分析仿真结果

  1. 使用图表展示数据

    • 使用“Chart”工具展示仿真结果,例如旅客的总等待时间分布图、安检口的通过率图、登机口的排队长度图等。
  2. 输出仿真报告

    • 使用“Output”工具输出仿真报告,包括统计数据和图表。

// 仿真结果分析

public class SimulationResults {

    public void analyze() {

        // 获取数据收集器

        PassengerDataCollector dataCollector = (PassengerDataCollector) getSimulation().getEngine().getDataCollector("passengerDataCollector");



        // 分析数据

        double[] arrivalTimes = dataCollector.getValues("arrivalTime");

        double[] securityCheckTimes = dataCollector.getValues("securityCheckTime");

        double[] shoppingTimes = dataCollector.getValues("shoppingTime");

        double[] boardingTimes = dataCollector.getValues("boardingTime");



        // 计算每个旅客的总等待时间

        double[] totalWaitTimes = new double[arrivalTimes.length];

        for (int i = 0; i < arrivalTimes.length; i++) {

            totalWaitTimes[i] = boardingTimes[i] - arrivalTimes[i];

        }



        // 输出统计数据

        System.out.println("Total number of passengers: " + arrivalTimes.length);

        System.out.println("Average total wait time: " + average(totalWaitTimes) + " minutes");

        System.out.println("Maximum total wait time: " + max(totalWaitTimes) + " minutes");

        System.out.println("Minimum total wait time: " + min(totalWaitTimes) + " minutes");



        // 创建图表

        createChart(totalWaitTimes, "Total Wait Time Distribution", "Passenger ID", "Wait Time (minutes)");

    }



    // 计算平均值

    private double average(double[] data) {

        double sum = 0.0;

        for (double value : data) {

            sum += value;

        }

        return sum / data.length;

    }



    // 计算最大值

    private double max(double[] data) {

        double max = data[0];

        for (double value : data) {

            if (value > max) {

                max = value;

            }

        }

        return max;

    }



    // 计算最小值

    private double min(double[] data) {

        double min = data[0];

        for (double value : data) {

            if (value < min) {

                min = value;

            }

        }

        return min;

    }



    // 创建图表

    private void createChart(double[] data, String title, String xLabel, String yLabel) {

        // 使用 AnyLogic 内置的图表工具

        Chart chart = new Chart(title);

        chart.setXLabel(xLabel);

        chart.setYLabel(yLabel);

        chart.addSeries("Total Wait Time", data);

        add(chart);

    }

}

5. 优化与改进

5.1 优化安检过程

  1. 增加安检资源

    • 通过增加安检口的数量或提高安检效率,减少旅客的等待时间。
  2. 调整安检时间

    • 根据仿真结果,调整安检所需的时间,使其更符合实际情况。

5.2 优化登机口排队

  1. 增加登机口资源

    • 通过增加登机口的数量或提高登机效率,减少旅客的等待时间。
  2. 调整登机时间

    • 根据仿真结果,调整登机所需的时间,使其更符合实际情况。

5.3 优化购物行为

  1. 增加商店资源

    • 通过增加商店的数量或提高商店的服务效率,减少旅客的等待时间。
  2. 调整购物时间

    • 根据仿真结果,调整购物所需的时间,使其更符合实际情况。

5.4 仿真结果的敏感性分析

  1. 设置参数变化范围

    • 通过设置不同的参数变化范围,进行敏感性分析,例如安检口数量、登机口数量、商店数量等。
  2. 运行多组仿真

    • 运行多组仿真实验,分析不同参数对仿真结果的影响。

// 敏感性分析

public class SensitivityAnalysis {

    public void run() {

        // 设置参数变化范围

        int[] securityCheckCapacity = {2, 3, 4, 5};

        int[] boardingGateCapacity = {4, 5, 6, 7};

        int[] shopCapacity = {3, 4, 5, 6};



        // 运行多组仿真实验

        for (int securitycapacity : securityCheckCapacity) {

            for (int boardingcapacity : boardingGateCapacity) {

                for (int shopcapacity : shopCapacity) {

                    // 设置当前参数

                    SecurityQueue securityQueue = (SecurityQueue) getSimulation().getEngine().getElement("securityQueue");

                    BoardingQueue boardingQueue = (BoardingQueue) getSimulation().getEngine().getElement("boardingQueue");

                    ShopQueue shopQueue = (ShopQueue) getSimulation().getEngine().getElement("shopQueue");



                    securityQueue.setCapacity(securitycapacity);

                    boardingQueue.setCapacity(boardingcapacity);

                    shopQueue.setCapacity(shopcapacity);



                    // 运行仿真

                    getSimulation().getEngine().run();



                    // 收集仿真结果

                    SimulationResults results = new SimulationResults();

                    results.analyze();



                    // 记录当前参数和结果

                    System.out.println("Security Check Capacity: " + securitycapacity);

                    System.out.println("Boarding Gate Capacity: " + boardingcapacity);

                    System.out.println("Shop Capacity: " + shopcapacity);

                    System.out.println("Average total wait time: " + results.getAverageWaitTime() + " minutes");

                    System.out.println("Maximum total wait time: " + results.getMaxWaitTime() + " minutes");

                    System.out.println("Minimum total wait time: " + results.getMinWaitTime() + " minutes");

                    System.out.println("-------------------------------------------------");

                }

            }

        }

    }

}

6. 结论

通过本案例研究,我们展示了如何在 AnyLogic 中进行机场旅客流动仿真。通过设置仿真环境、定义人群代理和行为、收集和分析数据,我们可以更好地理解旅客在机场的行为模式,并通过优化安检过程、登机口排队和购物行为,提高机场的运营效率和旅客的满意度。敏感性分析进一步帮助我们确定最优的资源配置方案,为机场的运营管理提供科学依据。在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐