2017-05-20 6 views
-2

このコードのサーバー数を増分数値に変更するにはどうすればいいですか?増分の間に待機時間を確認/計算できますか?MultiServerとcustomer-javaシミュレーションを作成する方法

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

は、私には宿題のように見える... – Michael

+0

はありません..それは..あなたが見る宿題ではありません、コードに誤りがない、私はちょうどそれがどのように機能するかを理解しようとし、それで遊んでいます。私はJavaプログラミングの初心者ですので、既存のプログラムコードで学ぶ方が早いと感じています。私はあなたがそのような初心者の質問を理解し、それに耐えて欲しいと思います。 :) – ClaraJackson

答えて

0

ただ、余分な機能を作成し、このように、パラメータとしてサーバーの数を渡す:

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)); 
     } 

あなたが表現して待機時間を得ることができます:「60 * ttwait/ttServed」、シミュレーション終了時:

// 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"); 

です。

Average waiting time: 1.9738361405998677 minutes 
Server free fraction: 47.27% 
Maximum queue length: 11 
Total customers arrived: 468 
Total customers served : 452 
Total customers >6min : 13 
fraction    : 0.028761061946902654 
server avg   : 2.1880341880341883 
============================================================================= 

Average percent of customers waiting more than 6 minutes (100 trials) : 3.2% 
+0

本当にありがとうDanilo M.Oliveira! :) – ClaraJackson

+0

私は総顧客到着を制御したいのですが、同じ方法ですか? – ClaraJackson

+0

私はあなたとは異なる答えを持っています。 。 @danilo M.Oliveira の平均待機時間:0.0分 Serverの遊離画分:808.43パーセント 最大キューの長さ:0 総顧客数が着い:470 総顧客数は役立った:470社の 総顧客数> 6分:0 割合:0.0 サーバーを平均:2.4191489361702128 – ClaraJackson

関連する問題