protected static void printResult(double[] result) {
   Statistics statisticResult = new Statistics(result);
   Log.printLine("Mean :" + statisticResult.getMean());
   Log.printLine("Median : " + statisticResult.median());
   Log.printLine("Variance : " + statisticResult.getVariance());
   Log.printLine("Std : " + statisticResult.getStdDev());
 }
  public static void main(String[] args) {
    try {
      Log.disable();
      // First step: Initialize the WorkflowSim package.
      /** Should change this based on real physical path */
      String daxPath = "E:\\PhD\\ComplexCloudSim\\config\\dax\\Montage_1000.xml";
      File daxFile = new File(daxPath);
      if (!daxFile.exists()) {
        Log.printLine(
            "Warning: Please replace daxPath with the physical path in your working environment!");
        return;
      }
      Parameters.PlanningAlgorithm pln_method = Parameters.PlanningAlgorithm.INVALID;
      ReplicaCatalog.FileSystem file_system = ReplicaCatalog.FileSystem.SHARED;
      OverheadParameters op = new OverheadParameters(0, null, null, null, null, 0);
      ClusteringParameters.ClusteringMethod method = ClusteringParameters.ClusteringMethod.NONE;
      ClusteringParameters cp = new ClusteringParameters(0, 0, method, null);

      // For each scheduling algorithm (FCFS,RR,MinMin,MaxMin), run 100 times
      for (int sche = 0; sche < 4; sche++) {
        Parameters.SchedulingAlgorithm sch_method;
        switch (sche) {
          case 0:
            sch_method = Parameters.SchedulingAlgorithm.FCFS;
            break;
          case 1:
            sch_method = Parameters.SchedulingAlgorithm.ROUNDROBIN;
            break;
          case 2:
            sch_method = Parameters.SchedulingAlgorithm.MINMIN;
            break;
          case 3:
            sch_method = Parameters.SchedulingAlgorithm.MAXMIN;
            break;
          default:
            sch_method = Parameters.SchedulingAlgorithm.FCFS;
        }
        for (int runs = 0; runs < numRuns; runs++) {
          Parameters.init(numVMs, daxPath, null, null, op, cp, sch_method, pln_method, null, 0);
          ReplicaCatalog.init(file_system);

          // before creating any entities.
          int num_user = 1; // number of grid users
          Calendar calendar = Calendar.getInstance();
          boolean trace_flag = false; // mean trace events

          // Initialize the CloudSim library
          CloudSim.init(num_user, calendar, trace_flag);

          ComplexDatacenter datacenter0 = createDatacenter("Datacenter_0");

          /** Create a WorkflowPlanner with one schedulers. */
          WorkflowPlanner wfPlanner = new WorkflowPlanner("planner_0", 1);
          /** Create a WorkflowEngine. */
          WorkflowEngine wfEngine = wfPlanner.getWorkflowEngine();
          /**
           * Create a list of VMs.The userId of a vm is basically the id of the scheduler that
           * controls this vm.
           */
          List<ComplexVM> vmlist0 = createVM(wfEngine.getSchedulerId(0));

          /** Submits this list of vms to this WorkflowEngine. */
          wfEngine.submitVmList(vmlist0, 0);

          /** Binds the data centers with the scheduler. */
          wfEngine.bindSchedulerDatacenter(datacenter0.getId(), 0);
          CloudSim.startSimulation();
          List<Job> outputList0 = wfEngine.getJobsReceivedList();
          CloudSim.stopSimulation();
          switch (sche) {
            case 0:
              FCFSResult[runs] = wfEngine.getWorkflowFinishTime();
              break;
            case 1:
              RoundRobinResult[runs] = wfEngine.getWorkflowFinishTime();
              break;
            case 2:
              MinMinResult[runs] = wfEngine.getWorkflowFinishTime();
              break;
            case 3:
              MaxMinResult[runs] = wfEngine.getWorkflowFinishTime();
              break;
            default:
              FCFSResult[runs] = wfEngine.getWorkflowFinishTime();
              break;
          }
        }
        Log.enable();
        Log.printLine(
            "------ "
                + numVMs
                + " VMs "
                + numRuns
                + " Runs with Damage Ratio "
                + damageRatio
                + "------");
        Log.printLine(">> FCFS");
        printResult(FCFSResult);
        Log.printLine(">> RoundRobin");
        printResult(RoundRobinResult);
        Log.printLine(">> MinMin");
        printResult(MinMinResult);
        Log.printLine(">> MaxMin");
        printResult(MaxMinResult);
      }
    } catch (Exception e) {
      Log.printLine("The simulation has been terminated due to an unexpected error");
    }
  }
  /**
   * Prints the job objects
   *
   * @param list list of jobs
   */
  protected static void printJobList(List<Job> list) {
    String indent = "    ";
    Log.printLine();
    Log.printLine("========== OUTPUT ==========");
    Log.printLine(
        "Job ID"
            + indent
            + "Task ID"
            + indent
            + "STATUS"
            + indent
            + "Data center ID"
            + indent
            + "VM ID"
            + indent
            + indent
            + "Time"
            + indent
            + "Start Time"
            + indent
            + "Finish Time"
            + indent
            + "Depth");
    DecimalFormat dft = new DecimalFormat("###.##");
    for (Job job : list) {
      Log.print(indent + job.getCloudletId() + indent + indent);
      if (job.getClassType() == Parameters.ClassType.STAGE_IN.value) {
        Log.print("Stage-in");
      }
      for (Task task : job.getTaskList()) {
        Log.print(task.getCloudletId() + ",");
      }
      Log.print(indent);

      if (job.getCloudletStatus() == Cloudlet.SUCCESS) {
        Log.print("SUCCESS");
        Log.printLine(
            indent
                + indent
                + job.getResourceId()
                + indent
                + indent
                + indent
                + job.getVmId()
                + indent
                + indent
                + indent
                + dft.format(job.getActualCPUTime())
                + indent
                + indent
                + dft.format(job.getExecStartTime())
                + indent
                + indent
                + indent
                + dft.format(job.getFinishTime())
                + indent
                + indent
                + indent
                + job.getDepth());
      } else if (job.getCloudletStatus() == Cloudlet.FAILED) {
        Log.print("FAILED");
        Log.printLine(
            indent
                + indent
                + job.getResourceId()
                + indent
                + indent
                + indent
                + job.getVmId()
                + indent
                + indent
                + indent
                + dft.format(job.getActualCPUTime())
                + indent
                + indent
                + dft.format(job.getExecStartTime())
                + indent
                + indent
                + indent
                + dft.format(job.getFinishTime())
                + indent
                + indent
                + indent
                + job.getDepth());
      }
    }
  }