队列模型(M/M/1)仿真程序实现

队列模型(M/M/1)仿真程序实现

编程实现队列模型(M/M/1)的仿真程序
输入参数:平均到达时间,平均服务时间,顾客数目,队列最大长度;
输出参数:队列中平均等待客户数;平均等待时间;服务器利用率。
(使用下一事件时间推进法仿真时间推进)

代码实现

Main.java

/* ----------
    created by hswyx666
    2020/10/28

 ---------- */

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.Font;
import java.util.Arrays;
import java.util.LinkedList;

public class Main {
    private JFrame frame = new JFrame("M/M/1 队列模型");
    private JLabel inputLabel = new JLabel("输入");
    private JLabel[] paramLabel = new JLabel[4];
    private JLabel outputLabel = new JLabel("输出");
    private JLabel[] resultsLabel = new JLabel[3];
    private JButton executeButton = new JButton("计算");
    private MyTextField[] inputTextField = new MyTextField[4];
    private MyTextField[] outputTextField = new MyTextField[3];
    private JLabel illegalLabel = new JLabel("输入数据不合法!");
    private JLabel explanationLabel = new JLabel("注:正在服务的顾客不算在队列内");

    private double averageArriveTime;
    private double averageServeTime;
    private int customerNum;
    private int maxQueueLen;

    private double[] arriveTimes;
    private double[] serveTimes;

    private double averageWaitNum;                  //平均等待数目
    private double averageWaitTime;                 //平均等待时间
    private double utilizeRate;                     //利用率

    private void setLayOut() {
        frame.setResizable(true);
        frame.setLayout(null);
        frame.setBounds(10, 10, 900, 600);
        frame.setLocation(500, 250);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setBackground(new Color(0x66ccff));                      //锦依卫色!!!

        inputLabel.setFont(new Font("宋体", Font.BOLD, 30));
        inputLabel.setForeground(Color.BLACK);
        inputLabel.setBounds(240, 40, 150, 40);
        frame.add(inputLabel);

        outputLabel.setFont(new Font("宋体", Font.BOLD, 30));
        outputLabel.setForeground(Color.BLACK);
        outputLabel.setBounds(550, 40, 150, 40);
        frame.add(outputLabel);

        String[] paramTexts = {"平均到达时间", "平均服务时间", "顾客数目", "队列最大长度"};

        for (int i = 0; i < 4; i++) {
            paramLabel[i] = new JLabel(paramTexts[i]);
            paramLabel[i].setFont(new Font("仿宋", Font.BOLD, 18));
            paramLabel[i].setBounds(80, 100 + i * 100, 150, 40);
            frame.add(paramLabel[i]);
            inputTextField[i] = new MyTextField();
            inputTextField[i].setBounds(200, 100 + i * 100, 150, 40);
            frame.add(inputTextField[i]);
        }

        String[] resultsTexts = {"平均等待客户数", "平均等待时间", "服务器利用率"};

        for (int i = 0; i < 3; i++) {
            resultsLabel[i] = new JLabel(resultsTexts[i]);
            resultsLabel[i].setFont(new Font("仿宋", Font.BOLD, 18));
            resultsLabel[i].setBounds(675, 100 + i * 150, 150, 40);
            frame.add(resultsLabel[i]);
            outputTextField[i] = new MyTextField();
            outputTextField[i].setBounds(500, 100 + 150 * i, 150, 40);
            frame.add(outputTextField[i]);
        }

        executeButton.setFont(new Font("宋体", Font.BOLD, 30));
        executeButton.setBounds(360, 475, 150, 50);
        executeButton.addMouseListener(new MyMouseListener(this));
        frame.add(executeButton);

        illegalLabel.setFont(new Font("等线", Font.BOLD, 15));
        illegalLabel.setBounds(375, 430, 150, 50);
        illegalLabel.setVisible(false);
        frame.add(illegalLabel);

        explanationLabel.setFont(new Font("等线", Font.BOLD, 15));
        explanationLabel.setBounds(600, 500, 250, 50);
        frame.add(explanationLabel);

        frame.setVisible(true);
    }

    void inputData() throws NumberFormatException {
        illegalLabel.setVisible(false);
        try {
            averageArriveTime = inputTextField[0].getDouble();
            averageServeTime = inputTextField[1].getDouble();
            customerNum = inputTextField[2].getInt();
            maxQueueLen = inputTextField[3].getInt();
        } catch (NumberFormatException e) {
            displayIllegalInformation();
        }
        if (customerNum <= 0 || maxQueueLen < 0) {
            throw new NumberFormatException();
        }
    }

    void calculate() {
        arriveTimes = new double[customerNum];
        serveTimes = new double[customerNum];
        arriveTimes[0] = -averageArriveTime * Math.log(1 - Math.random());
        for (int i = 1; i < customerNum; i++) {
            double r1 = Math.random();
            arriveTimes[i] = arriveTimes[i - 1] - averageArriveTime * Math.log(1 - r1);       //指数分布
        }
        double firstArriveTime = arriveTimes[0];
        for (int i = 0; i < customerNum; i++) {
            arriveTimes[i] -=  firstArriveTime;
        }
        for (int i = 0; i < customerNum; i++) {
            double r2 = Math.random();
            double randomArriveTime = -averageServeTime * Math.log(1 - r2);      //指数分布
            serveTimes[i] = randomArriveTime;
        }
        double lastLeaveTime = 0;                                                //上一位顾客离开时间
        int newCustomerNum = clearIllegalCustomer();
        double[] leaveTimes = new double[newCustomerNum];
        double[] waitTimes = new double[newCustomerNum];                           //等待时间
        for (int i = 0; i < newCustomerNum; i++) {
            if (arriveTimes[i] < lastLeaveTime) {
                leaveTimes[i] = serveTimes[i] + lastLeaveTime;
                waitTimes[i] = lastLeaveTime - arriveTimes[i];
            }
            else {
                leaveTimes[i] = arriveTimes[i] + serveTimes[i];
                waitTimes[i] = 0;
            }
            lastLeaveTime = leaveTimes[i];
        }
        double workTimeSum = 0;
        for (double serveTime: serveTimes) {
            workTimeSum += serveTime;
        }
        utilizeRate = workTimeSum / (leaveTimes[newCustomerNum - 1] + firstArriveTime);
        double waitTimeSum = 0;
        for (double waitTime: waitTimes) {
            waitTimeSum += waitTime;
        }
        averageWaitNum = waitTimeSum / (leaveTimes[newCustomerNum - 1] + firstArriveTime);
        averageWaitTime = waitTimeSum / (double)newCustomerNum;
    }

    private int clearIllegalCustomer() {                   //去掉因等待队列过长离开的顾客
        double lastLeaveTime = 0;
        LinkedList<Double> legalArriveTimes = new LinkedList<>();
        LinkedList<Double> legalServeTimes = new LinkedList<>();
        for (int i = 0; i < customerNum; i++) {
            legalArriveTimes.add(arriveTimes[i]);
            legalServeTimes.add(serveTimes[i]);
        }
        for (int i = 0; i < legalArriveTimes.size(); i++) {
            if (legalArriveTimes.get(i) < lastLeaveTime) {
                lastLeaveTime += legalArriveTimes.get(i);
            }
            else {
                lastLeaveTime = legalArriveTimes.get(i) + legalServeTimes.get(i);
            }
            int j;
            for (j = i + 1; j < legalArriveTimes.size(); j++) {
                if (legalArriveTimes.get(j) > lastLeaveTime) {
                    break;
                }
            }
            for (j--; j > i; j--) {                         //一定要反向删除
                if (j - i > maxQueueLen) {
                    legalArriveTimes.remove(j);
                    legalServeTimes.remove(j);
                }
            }
        }
        arriveTimes = new double[legalArriveTimes.size()];
        serveTimes = new double[legalServeTimes.size()];
        for (int i = 0; i < legalArriveTimes.size(); i++) {
            arriveTimes[i] = legalArriveTimes.get(i);
            serveTimes[i] = legalServeTimes.get(i);
        }
        return legalArriveTimes.size();
    }

    void outputData() {
        outputTextField[0].setText(String.format("%.3f", averageWaitNum));
        outputTextField[1].setText(String.format("%.3f", averageWaitTime));
        outputTextField[2].setText(String.format("%.2f%%", utilizeRate * 100));
    }

    void displayIllegalInformation() {
        illegalLabel.setVisible(true);
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.setLayOut();
    }

}

MyMouseListener.java

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class MyMouseListener implements MouseListener {
    private Main main;

    MyMouseListener(Main main) {
        this.main = main;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1) {
            try {
                main.inputData();
                main.calculate();
                main.outputData();
            } catch (NumberFormatException ex) {
                main.displayIllegalInformation();
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}

MyTextField.java

import javax.swing.JTextField;
import java.awt.Font;

class MyTextField extends JTextField {
    MyTextField() {
        super();
        setFont(new Font("楷体", Font.BOLD, 20));
        setHorizontalAlignment(LEFT);
    }

    double getDouble() throws NumberFormatException {
        return new Double(getText());
    }

    int getInt() throws NumberFormatException {
        return new Integer(getText());
    }
}

运行截图

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值