如何将此代码中的服务器数量更改为增量编号:5,10,15,10,并且在增量期间,我可以检查/计算等待时间?
import java.util.ArrayList;
import java.text.DecimalFormat;
public class Simulate3 {
private static boolean openPosition;
private static double fractionAvg = 0.0;
private static DecimalFormat percent;
public static void main(String[] args)
{
double Mean_Exponential_iat = 10.0;
double Mean_erlang_completion_distribution = 2.0;
int Time_until_theEnd_of_WorkDay = 8;
/**
* By starting and finishing shift with 1 server, almost 98.484848% of customers wait more than 6 mins with the avg wait time at 218 hours.
* With 2 servers the avg wait time is 13 hours with 69.1489% waiting more than 6 mins.
* With 3 servers the avg waiting time is 26mins with 0% of customers waiting more than 6 mins.
* Therefore the optimal allocation will be by assigning 2 servers to start off the shift and when the need arises, open a new position of service.
* If 1 server alone starts, the fraction in close to 16%.
* By starting with 2 servers the fraction is 4.3%.
*/
int The_number_of_servers_in_the_branch =0;
long seed = +5; // The starting seed for the random number generator
int trials =10;//The number of times the simulation will be repeated for the average statistics
for (int i = 1; i <= trials; i++)// Conduct a number of trials in order to get the average fraction of customers waiting more than 6 mins.
//Use different seed in each trial.
{
simulateNServers(Mean_Exponential_iat, Mean_erlang_completion_distribution, Time_until_theEnd_of_WorkDay, The_number_of_servers_in_the_branch, seed);
seed++;
}
double trialAvg = fractionAvg/trials;
percent = new DecimalFormat("0.#%");
System.out.println("=============================================================================");
// System.out.println("////");
System.out.println("Average percent of task waiting more than 6 minutes (100 trials) : "+ percent.format(trialAvg));
System.out.println("=============================================================================");
}
/**
* Static method to run a simulation with certain parameters. It outputs the following statistical data.
*
* Average waiting time :
* Server free fraction : [The percentage of the servers being free]
* Maximum queue length :
* Total customers arrived: [Total arrivals of customers within the work-day]
* Total customers served : [Total customers served within the work-day]
* Total customers >6min : [Total number of customers that waited more than 6 minutes to be served, within the work-day]
* fraction : [Percentage of customers that waited more than 6 minutes in the queue]
*
* @param lambdaA : Mean of exponential inter-arrival distribution.
*
* @param lambdaS : Mean of erlang completion distribution.
*
* @param tEnd : The time until the end of the work-day
*
* @param nserv : The number of servers in the branch
*
* @param seed
*/
public static void simulateNServers(double Mean_Exponential_iat, double Mean_erlang_completion_distribution, double Time_until_theEnd_of_WorkDay, int The_number_of_servers_in_the_branch, long seed)
{
The_number_of_servers_in_the_branch +=5;
Queue q = new Queue(); // Initializes up the Queue
ArrayList<Server> serverFree = new ArrayList<Server>(); // Create list of servers
MyRandom r = new MyRandom(seed); // Initializes the random number generator
int k = 10; // Initializes the kappa of the Erlang distribution
double clock = 0; // Start of time
double Time_to_next_arrival = 0.0; // Time to next arrival
//double[] tnc = new double[nserv]; // Times of size nserv of completion for every server [i]
//
double endTime = Time_until_theEnd_of_WorkDay; // Minutes until endtime
int Number_of_Total_Events = 0; // Number of total events
int Number_of_total_arrivals = 0; // Number of total arrivals
double The_Time_to_the_NextEvent = 0.0; // The time to the next event
int Max_Q_length = 0; // Max Q length
double Time_free_at_each_instance = 0.0; // Time free at each instance
double Total_server_free_time = 0.0; // Total server free time
double ttServerFree = 0.0;
double Total_Waiting_Time = 0.0; // Total waiting time
double Total_Number_of_Tasks = 0.0; // Total Number of Customers
double Number_of_customers_waiting_more_than_6Minutes = 0.0; // Number of customers waiting more than 6 minutes
int The_Total_Number_of_Servers_BUSY_for_all_events = 0; // The total number of servers busy for all events
int prevHour = 0; // Keeping track of which hour has finished
int hourStartEvent = 0;
int serverSum = 5;
double serverHourlyAvg = 0.0;
for (int i = 0; i < The_number_of_servers_in_the_branch; i++) // Initialize the servers' status
{
serverFree.add(new Server(true));
}
Server tmpSrv = serverFree.get(0); // Initialise the first completion time to 0.0
tmpSrv.setTnc(0.0);
serverFree.set(0, tmpSrv);
// Primary simulation loop
while (true) {
boolean arrivalEvent = false; // The type of the next event, arrival
// or otherwise
boolean serviceEvent = false; // The type of the next event, service
// or otherwise
// Keep track of previous event for server free statistics
double prevEvent = 0.0;
// Check if the length of the Q is the largest
if (q.length() > Max_Q_length)
{
Max_Q_length = q.length();
}
//Keep track of the fraction of customers waiting more than 6mins
//This should not exceed 5% on average
double fraction = Number_of_customers_waiting_more_than_6Minutes / Total_Number_of_Tasks;
//System.out.println("============================================ " );
//System.out.println("fraction: " + fraction); // Print out the fraction per event
int servers=serverFree.size(); // Prints out the number of servers
//System.out.println("============================================ " );
//System.out.println("nserv: " + nserv);
// Keep track of how many servers are busy
The_Total_Number_of_Servers_BUSY_for_all_events += busyServersNo(serverFree);
double tnc;// Get the next completion time from all servers
Server tmp = getNextTNC(serverFree);
if(tmp!=null) tnc = tmp.getTnc();
else tnc=Double.POSITIVE_INFINITY;
int tnc_index = serverFree.indexOf(tmp);
// Check if the next event is a feasible arrival time
The_Time_to_the_NextEvent = Math.min(Time_to_next_arrival, tnc);
if (The_Time_to_the_NextEvent == Time_to_next_arrival && Time_to_next_arrival != tnc)
{
arrivalEvent = true;
serviceEvent = false;
} else if (The_Time_to_the_NextEvent == tnc && Time_to_next_arrival != tnc)
{
serviceEvent = true;
arrivalEvent = false;
} else if (Time_to_next_arrival == tnc) {
arrivalEvent = true;
}
// Update the clock
if (The_Time_to_the_NextEvent != Double.POSITIVE_INFINITY) {
prevEvent = clock;
clock = The_Time_to_the_NextEvent ;
}
/**
* In this block I'll be keeping some statistics for the average
* allocation of servers per hour
*/
int currHour=(int) clock;
if(currHour==prevHour)
{
serverSum+=servers;
}
else if (currHour>=prevHour)
{
serverHourlyAvg= (double) serverSum/(Number_of_Total_Events - hourStartEvent);
System.out.println("Avg servers for hour "+ currHour + " : "+ serverHourlyAvg);
serverSum = 0;
hourStartEvent= Number_of_Total_Events ;
prevHour=currHour;
}
/**
* Every time the cycle begins there needs to be a check whether the optimality constraint is met.
* This constraint is that the queue is no larger than 6 customers.
* If it is not, then the algorithm needs to set up a flag that will increase the number of servers until the constraint is satisfied.
*
*/
if (q.length()>10)
{
openPosition=true;
}
else openPosition=false;
int id = getFreeServer(serverFree); // Get the index of the next available server
if (q.isEmpty() && clock >= endTime && tnc == Double.POSITIVE_INFINITY) // BRANCH_1// Check if the condition to stop the simulation has been met.
{
percent = new DecimalFormat("0.0#%");
System.out.println("==================================================================");
System.out.println("The number of servers : " + servers);
System.out.println("Maximum queue length: " + Max_Q_length);
System.out.println("Total tasks arrived: " + Number_of_total_arrivals);
System.out.println("Total tasks served : " + (int) Total_Number_of_Tasks);
System.out.println("The_number_of_servers_in_the_branch : " + The_number_of_servers_in_the_branch);
System.out.println("Average waiting time: " + 60* Total_Waiting_Time / Total_Number_of_Tasks + " minutes");
System.out.println("Server free fraction: " + percent.format(Total_server_free_time / ttServerFree));
System.out.println("Total tasks waiting >6min : " + (int) Number_of_customers_waiting_more_than_6Minutes);
System.out.println(" fraction : " + fraction);
fractionAvg+=fraction;
break;
}
if (arrivalEvent && clock < endTime) // BRANCH_2// This is an arrival event and the end time is not reached
{
if (id != -1)
Time_free_at_each_instance = clock - prevEvent;
ttServerFree += Time_free_at_each_instance;
Total_server_free_time += Time_free_at_each_instance * freeServersNo(serverFree);
if (freeServersNo(serverFree) != 0) // Report how many servers are free and for how long
//System.out.println(freeServersNo(serverFree) + " server(s) are free for " + timeFree + " hours. Total= " + ttServer);
Time_to_next_arrival = clock + r.nextExponential(getLambda(clock));// Sample for next arrival time so long that it doens't exceed endTime
if (Time_to_next_arrival > Time_until_theEnd_of_WorkDay)
{
Time_to_next_arrival = Double.POSITIVE_INFINITY;
}
Number_of_total_arrivals++;
if (id != -1) // BRANCH_3_YES // Inner conditional loop to check if there is at least one server free
{ // Mark the server as busy by replacing the object in the arraylist
Server tmpSrv0 = serverFree.get(id);
tmpSrv0.setState(false);
tmpSrv0.setTnc(clock + r.nextErlang(k, Mean_erlang_completion_distribution)); // Sample for time of next completion
serverFree.set(id, tmpSrv0);
}
else {// BRANCH_3_NO
q.put(clock);// Put person in the queue
// If there is need for servers add one here
if (openPosition) serverFree.add(new Server(true));
}
// Print out the arrival event
System.out.println(" Number_of_Total_Events arrival: " + Number_of_Total_Events + " " + "" + " Queue length: " + q.length() + " Time: " + clock);
if (q.isEmpty())
{
// System.out.println("Guy is served, has waited: 0.0");
Total_Number_of_Tasks++;
}
}
else
{
if (serviceEvent) // BRANCH_4_YES// This is a service completion event
{
if (id != -1)
Time_free_at_each_instance = clock - prevEvent;
ttServerFree += Time_free_at_each_instance;
Total_server_free_time += Time_free_at_each_instance * freeServersNo(serverFree);
if (freeServersNo(serverFree) != 0)// Report how many servers are free and for how long
System.out.println(freeServersNo(serverFree) + " server(s) are free for " + Time_free_at_each_instance + " hours." + " Total_server_free_time : " + Total_server_free_time );
// BRANCH_5_YES// Inner conditional loop to check if the
// queue is empty
if (q.isEmpty())
{
// If there is no more need; release the additional server
if (!openPosition && serverFree.size()>The_number_of_servers_in_the_branch && id!=-1) serverFree.remove(id);
// Get the first busy server and release them
int busy = serverFree.indexOf(getNextTNC(serverFree));
if (busy != -1){
// Mark the server as busy by replacing the object in the arraylist
Server tmpSrv1 = serverFree.get(busy);
tmpSrv1.setState(true);
serverFree.set(busy, tmpSrv1);
}
if (busy != -1){
Server tmpSrv2 = serverFree.get(busy);
tmpSrv2.setTnc(Double.POSITIVE_INFINITY);
serverFree.set(busy, tmpSrv2);
}
}// End of yes in Condition 5
else {// BRANCH_5_NO//
// Get person from queue
double t = q.get();
// Log the served customer
Total_Number_of_Tasks++;
// Check which customers waited more than 6 minutes (0.1
// of the hour)
if ((clock - t) > 0.1)
{
Number_of_customers_waiting_more_than_6Minutes++; // If it took more than 6 minutes to serve, log it.
}
System.out.println("Tasks is served, has waited: " + (clock - t));
Total_Waiting_Time += (clock - t); // Update the sum of waiting times
// Sample for time of next completion
Server tmpSrv3 = serverFree.get(tnc_index);
tmpSrv3.setTnc(clock + r.nextErlang(k, Mean_erlang_completion_distribution));
serverFree.set(tnc_index, tmpSrv3);
}// End of no in Condition 5
// Write out the Completion of the event
int event = tnc_index + 1;
System.out.println(" Number_of_Total_Events : "+ Number_of_Total_Events + " " + "completed : " + event + " " + "Queue length: " + q.length() + " Time: " + clock);
}// End of Condition 4
else {// BRANCH_4_NO//
// Set next arrival time to very large number
Time_to_next_arrival = Double.POSITIVE_INFINITY;
}// End of Infinite arrival time
}// End of no in Condition 2
// Increment the number of events
Number_of_Total_Events++;
}// End of while loop
}// End of static main method
/**
* Method to get the appropriate average of arriving customers per hour of service. The distributions were provided by the manager.
* They can be changed to any measured distribution.
*
* @param Clock
* The current time
* @return The average customers arriving for this hour
*/
private static double getLambda(double clock)
{
switch ((int) clock)
{
case 0:
return 1.0;
case 1:
return 2.0;
case 2:
return 3.0;
case 3:
return 4.0;
case 4:
return 5.0;
case 5:
return 6.0;
case 6:
return 7.0;
case 7:
return 8.0;
default:
return 0;
}
}
/**
* Find the first server that is free.
* @param serverFree The arraylist in which to look for a free server
* @return The index of the position of the first free server
*/
private static int getFreeServer(ArrayList<Server> serverFree) {
for (Server server : serverFree) {
boolean state = server.isState();
if (state){
return serverFree.indexOf(server);
}
}return -1;
}// End of getFreeServer method
/**
* Find the first server that is busy.
* @param serverFree The arraylist in which to look for a busy server
* @return The index of the position of the first busy server
*/
private static int getBusyServer(ArrayList<Server> serverFree)
{
for (Server server : serverFree)
{
boolean state = server.isState();
if (state){
return serverFree.indexOf(server);
}
}return -1;
}// End of getFreeServer method
/**
* Count the free servers
* @param serverFree The arraylist in which to look for a free server
* @return The number of servers that are free
*/
private static int freeServersNo(ArrayList<Server> serverFree)
{
int servers = 0;
for (Server server : serverFree) {
boolean state = server.isState();
if (state)
servers++;
}
return servers;
}// End of freeServersNo method
/**
* Count the busy servers
* @param serverFree The arraylist in which to look for a busy server
* @return The number of servers that are busy
*/
private static int busyServersNo(ArrayList<Server> serverFree)
{
int servers =0;
for (Server server : serverFree) {
boolean state = server.isState();
if (!state)
servers++;
}
return servers;
}// End of busyServersNo method
/**
* Find the server with the lowest completion time
* @param tnc_min The arraylist to search for completion times
* @return The index of the lowest time of completion
*/
private static Server getNextTNC(ArrayList<Server> serverFree)
{
double tnc_min = Double.POSITIVE_INFINITY;
Server index = null;
for (Server server : serverFree)
{
if(server.getTnc() < tnc_min) {
tnc_min = server.getTnc();
index=server;
}
}
return index;
}// End of getNextTNC method
}// End of Class
答案 0 :(得分:0)
只需创建一个额外的函数并将服务器数量作为参数传递,如下所示:
iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner ! --uid-owner 0 -j DNAT --to 127.0.0.1:8080
您可以在模拟结束时使用以下表达式获取等待时间:&#34; 60 * ttwait / ttServed&#34;:
public static void main(String[] args) {
double lambdaA = 58.0;
double lambdaS = 30.0;
double tEnd = 8.0;
/**
* By starting and finishing shift with 1 server, almost 98.484848% of
* customers wait more than 6 mins with the avg wait time at 218 hours.
* With 2 servers the avg wait time is 13 hours with 69.1489% waiting
* more than 6 mins. With 3 servers the avg waiting time is 26mins with
* 0% of customers waiting more than 6 mins. Therefore the optimal
* allocation will be by assigning 2 servers to start off the shift and
* when the need arises, open a new position of service. If 1 server
* alone starts, the fraction in close to 16%. By starting with 2
* servers the fraction is 4.3%.
*/
// int nserv = 2;
int[] servers = {5, 10, 15, 10};
for (int nserv : servers) {
simulateServers(lambdaA, lambdaS, tEnd, nserv);
}
}
private static void simulateServers(double lambdaA, double lambdaS, double tEnd, int nserv) {
// The starting seed for the random number generator
long seed = 12342;
//The number of times the simulation will be repeated for the average statistics
int trials = 100;
// Conduct a number of trials in order to get the average fraction of customers
// waiting more than 6 mins. Use different seed in each trial.
for (int i = 1; i <= trials; i++) {
simulateNServers(lambdaA, lambdaS, tEnd, nserv, seed);
seed++;
}
double trialAvg = fractionAvg / trials;
percent = new DecimalFormat("0.#%");
System.out.println("=============================================================================");
System.out.println();
System.out.println("Average percent of customers waiting more than 6 minutes (100 trials) :
" + percent.format(trialAvg));
}
// Get the index of the next available server
int id = getFreeServer(serverFree);
// BRANCH_1// Check if the condition to stop the simulation has been met.
if (q.isEmpty() && clock >= endTime
&& tnc == Double.POSITIVE_INFINITY) {
percent = new DecimalFormat("0.0#%");
System.out.println("Average waiting time: " + 60 * ttwait
/ ttServed + " minutes");