M/M/C(马科洛夫队列)是一个多服务器的排队模型,每个客户到来的时候选择等待队列最短的服务窗口排队等待服务,在商场,银行等服务行业应用广泛,模型如下:
使用服从指数分布的随机数(平均值为lamda)模拟每个客户到达间隔时间,使用服从正态分布的随机数(平均数为mu,标准差为sigma)模拟每个客户在服务窗口接受服务时间,给定服务窗口数,最大客户数,以及lamda,mu和sigma之后,程序进行模拟运算之后可以给出实际计算的lamda,mu和sigma,已经平均队列长度,平均等待时间,平均停留时间等等。程序代码如下:
首先,产生服从指数分布和正太分布伪随机数的算法如下(从网上找到的代码):
import java.util.Random;
/**
* Generate the specify type random number
*/
public class RandomGenerator {
/**
* Generate normal distribute random number
* @param average Expect average
* @param sigma Standard devation
* @return Normal distribute random number
*/
public static double generateNormalDistrRand(double average,
double sigma) {
double N = 12;
double x = 0, temp = N;
do {
x = 0;
for (int i = 0; i < N; i++)
x = x + (Math.random());
x = (x - temp / 2) / (Math.sqrt(temp / 12));
x = average + x * Math.sqrt(sigma);
} while (x <= 0);
return x;
}
/**
* Generate negative index distribute random number
* @param lamda Expect average
* @return Negative index distribute random number
*/
public static double generateNegativeIndexDistrRand(double lamda) {
Random random = new Random();
return -Math.log(random.nextDouble()) / lamda;
}
}
客户模型:
public class Customer {
private double arrivalTime = 0.0;//客户到达时刻
private double serviceTime = 0.0;//客户接受服务的时间
private double departureTime = 0.0;//客户离开时刻=客户到达时刻+客户等待时间+客户接受服务时间
private int queueLen;
public double getDepartureTime() {
return departureTime;
}
public void setDepartureTime(double departureTime) {
this.departureTime = departureTime;
}
public double getArrivalTime() {
return arrivalTime;
}
public void setArrivalTime(double arrivalTime) {
this.arrivalTime = arrivalTime;
}
public double getServiceTime() {
return serviceTime;
}
public void setServiceTime(double serviceTime) {
this.serviceTime = serviceTime;
}
@Override
public String toString() {//客户停留时间=客户离开时刻-客户到达时刻,客户等待时间=客户离开时刻-客户到达时刻-客户接受服务时间
return "Customer stay time = " + (departureTime - arrivalTime)
+ ", and wait time = "
+ (departureTime - arrivalTime - serviceTime);
}
public void setQueueLen(int size) {
this.queueLen = size;
}
public int getQueueLen() {
return this.queueLen;
}
}
使用多线程模拟服务窗口:
public class Server implements Runnable {
private int serverId;
private volatile boolean isAlive = true;
private Deque<Customer> customerQueue = new LinkedBlockingDeque<Customer>();//每个服务窗口都有一个客户等待队列
private int custoemrServed = 0;
private