续:队列的应用 之 M/D/1队列

来源:互联网 发布:春光灿烂猪八戒 知乎 编辑:程序博客网 时间:2024/05/22 06:13
 模拟:

        MD1Queue 是 Queue 客户端 ,你可能使用它来验证这类数学结果。他是基于事件模拟的简单示例:我们产生的事件发生在特定时间,为了事件相应的调整我们的数据结构,模拟当事件出现时,发生了什么。在M/D/1队列中,有两类事件:不是有顾客到达,就是提供顾客服务,因此我们需要维护两个变量:


   · nextService 是下一个服务的时间
   · nextArrival   是下一个到达的时间

        为了模拟到达事件,在队列中插入double值,nextvalArrival是到达时间;为了模拟服务,中队列中删除值,计算等待时间(离开队列时间减去服务时间nextService是到达时间)并将等待时间数据点加到直方图上(直方图程序Histogram)。在多次试验之后,结果的形状是M/D/1排队系统的特性。从实用观点来看,这个过程中的一个最重要特征是,通过使用不同的λ和μ值运行MD1Queue,你会发现当服务率逼近到达率时,平均等待时间和队列长度可能剧增。当服务费率很高时,直方图有一个可见的尾部,此时随着等待时间的减少,顾客需要等待时间的频率减少到几乎可以忽略不计。但是,当服务费率逼近到达率时,直方图的尾部在最多值处伸展,因此至少能显示顾客最长等待时间频率。

view plaincopy to clipboardprint?01./************************************************************************* 02. *  Compilation:  javac MD1Queue.java 03. *  Execution:    java MD1Queue lambda mu 04. *  Dependencies: Queue.java 05. * 06. *  % java MD1Queue .167 .25 07. * 08. *  % java MD1Queue .167 .22 09. *  10. *************************************************************************/  11.  12.public class MD1Queue {   13.  14.    public static void main(String[] args) {   15.        double lambda = Double.parseDouble(args[0]);   // arrival rate   16.        double mu     = Double.parseDouble(args[1]);   // service rate   17.  18.        Histogram hist = new Histogram(60 + 1);  19.        Queue<Double> queue = new Queue<Double>();  20.        StdDraw.setCanvasSize(700, 500);  21.  22.        double nextArrival = StdRandom.exp(lambda);    // time of next arrival   23.        double nextService = nextArrival + 1/mu;       // time of next completed service   24.  25.        while (true) {  26.  27.            // next event is an arrival   28.            while (nextArrival < nextService) {  29.                queue.enqueue(nextArrival);  30.                nextArrival += StdRandom.exp(lambda);  31.            }   32.  33.            // next event is a service completion   34.            double arrival = queue.dequeue();  35.            double wait = nextService - arrival;  36.  37.            // update the histogram   38.            StdDraw.clear();  39.            hist.addDataPoint(Math.min(60,  (int) (Math.round(wait))));  40.            hist.draw();  41.            StdDraw.show(20);  42.  43.            // update the queue   44.            if (queue.isEmpty()) nextService = nextArrival + 1/mu;  45.            else                 nextService = nextService + 1/mu;  46.        }   47.    }   48.}   
01.public class Histogram {  02.    private final double[] freq;   // freq[i] = # occurences of value i   03.    private double max;            // max frequency of any value   04.  05.    public Histogram(int N) {  06.        freq = new double[N];  07.    }  08.  09.    // Add one occurrence of the value i.    10.    public void addDataPoint(int i) {  11.        freq[i]++;   12.        if (freq[i] > max) max = freq[i];   13.    }   14.  15.    // draw (and scale) the histogram.   16.    public void draw() {  17.        StdDraw.setYscale(0, max);  18.        StdStats.plotBars(freq);  19.    }  20.   21.    public static void main(String[] args) {  22.        int N = Integer.parseInt(args[0]);   // number of coins   23.        int T = Integer.parseInt(args[1]);   // number of trials   24.  25.        // create the histogram   26.        Histogram histogram = new Histogram(N+1);   27.        for (int t = 0; t < T; t++) {  28.            histogram.addDataPoint(Bernoulli.binomial(N));  29.        }  30.  31.        // display using standard draw   32.        StdDraw.setCanvasSize(500, 100);  33.        histogram.draw();  34.    }   35.}   
01.import java.util.Iterator;  02.import java.util.NoSuchElementException;  03.  04.public class Queue<Item> implements Iterable<Item>  05.{  06.    private int N; // number of elements on queue   07.    private Node first; // beginning of queue   08.    private Node last; // end of queue   09.  10.    private class Node  11.    {  12.        private Item item;  13.        private Node next;  14.    }  15.  16.    public Queue()  17.    {  18.        first = null;  19.        last = null;  20.    }  21.  22.    public boolean isEmpty()  23.    {  24.        return first == null;  25.    }  26.  27.    public int length()  28.    {  29.        return N;  30.    }  31.  32.    public void enqueue(Item item)  33.    {  34.        Node x = new Node();  35.        x.item = item;  36.        if (isEmpty())  37.        {  38.            first = x;  39.            last = x;  40.        }  41.        else  42.        {  43.            last.next = x;  44.            last = x;  45.        }  46.        N++;  47.    }  48.  49.    // remove and return the least recently added item   50.    public Item dequeue()  51.    {  52.        if (isEmpty())  53.            throw new RuntimeException("Queue underflow");  54.        Item item = first.item;  55.        first = first.next;  56.        N--;  57.        return item;  58.    }  59.  60.    public Iterator<Item> iterator()  61.    {  62.        return new QueueIterator();  63.    }  64.  65.    // an iterator, doesn't implement remove() since it's optional   66.    private class QueueIterator implements Iterator<Item>  67.    {  68.        private Node current = first;  69.  70.        public boolean hasNext()  71.        {  72.            return current != null;  73.        }  74.  75.        public void remove()  76.        {  77.            throw new UnsupportedOperationException();  78.        }  79.  80.        public Item next()  81.        {  82.            if (!hasNext())  83.                throw new NoSuchElementException();  84.            Item item = current.item;  85.            current = current.next;  86.            return item;  87.        }  88.    }  89.  90.}  

       像我们在许多其他应用中所分析的一样,使用模拟来验证还不完全理解的数学模型试验就更个复杂情况的一个起点。在队列中的实际应用中,我们可以有多个队列,多台服务器,多级服务器,限制队列大小和许多其他限制。而且,到达分布和服务时间可能不能用数学方式描述。在这写情况下,我们不可能求助于其他,只能使用模拟。我们可以更多的使用模拟来调整系统设计参数(比如:服务率)来适当反映外部的环境(比如:到达率)。

本文链接地址为:http://blog.csdn.net/jertvip/article/details/6590447