/** 初期化 */
 private void init() {
   ArrayList<Role> rl = createRoleList(); // エージェントにセットされるロール変数
   a = new MiniAgent("a"); // エージェントの初期化
   a.setRole(rl); // ロールリストをセット
   b = new MiniAgent("b");
   rl = createRoleList(); // ロールリストの生成
   b.setRole(rl); // ロールリストをセット
   c = new MiniAgent("c");
   rl = createRoleList();
   c.setRole(rl);
 }
 /**
  * 引数のエージェントをコンソールに表示する
  *
  * @param ma
  */
 private void printAgent(MiniAgent a, MiniAgent b, MiniAgent c) {
   ArrayList<Role> rl1 = a.getRoles(); // ロールを取得
   ArrayList<Role> rl2 = b.getRoles(); // ロールを取得
   ArrayList<Role> rl3 = c.getRoles();
   System.out.println(
       a.getName()
           + "\t av:tm(cost)\t\t"
           + b.getName()
           + "\t av:tm(cost)\n"
           + c.getName()
           + "\t av:tm(cost)\n");
   // ロールの表示
   for (int i = 0; i < rl1.size(); i++) {
     Role r1 = rl1.get(i);
     Role r2 = rl2.get(i);
     Role r3 = rl3.get(i);
     System.out.print(
         r1.getName()
             + "\t"
             + r1.getAbility()
             + ":"
             + r1.getVolume()
             + "("
             + r1.getRoleCost()
             + ")");
     System.out.print("\t\t");
     System.out.print(
         r2.getName()
             + "\t"
             + r2.getAbility()
             + ":"
             + r2.getVolume()
             + "("
             + r2.getRoleCost()
             + ")");
     System.out.println();
     System.out.print(
         r3.getName()
             + "\t"
             + r3.getAbility()
             + ":"
             + r3.getVolume()
             + "("
             + r3.getRoleCost()
             + ")");
     System.out.println();
   }
   System.out.println(
       "\t\t("
           + a.getTotalRoleCost()
           + ")\t\t\t\t("
           + b.getTotalRoleCost()
           + ")\t\t\t\t("
           + c.getTotalRoleCost()
           + ")");
   System.out.println();
 }
  /** シミュレーション開始地点 */
  public void start() {
    ArrayList<String> writeList = new ArrayList<String>(); // 書き出し用文字列を保持するリスト
    for (int i = 0; i < SIM_NUM; i++) {
      init(); // 初期化
      // 書き出し用
      double pTotal_a = 0, pTotal_b = 0, pTotal_c = 0;
      double total_a = 0, total_b = 0, total_c = 0;
      // printAgent(a,b); // 表示
      pTotal_a = a.getTotalRoleCost(); // 交換前のaのトータルロールコスト
      pTotal_b = b.getTotalRoleCost(); // 交換前のbのトータルロールコスト
      pTotal_c = c.getTotalRoleCost(); // 交換前のcのトータルロールコスト

      exchangeRoleBigger(a, b, c); // ロールの交換

      // printAgent(a,b); // 表示
      total_a = a.getTotalRoleCost(); // 交換後のaのトータルロールコスト
      total_b = b.getTotalRoleCost(); // 交換後のbのトータルロールコスト
      total_c = c.getTotalRoleCost(); // 交換後のcのトータルロールコスト
      System.out.println(
          "a:"
              + (total_a - pTotal_a)
              + "\nb:"
              + (total_b - pTotal_b)
              + "\nc:"
              + (total_c - pTotal_c)
              + "\n");
      writeList.add(
          (total_a - pTotal_a)
              + ","
              + (total_b - pTotal_b)
              + ","
              + (total_c - pTotal_c)); // 書き出し用文字列に追加
    }
    CSVReaderWriter.write(FILE, writeList); // csv形式で書き出し

    // 分析
    double total_a = 0, total_b = 0, total_c = 0; // それぞれの短縮時間の合計
    ArrayList<String[]> read = new ArrayList<String[]>(); // 読み込み用リスト
    read = CSVReaderWriter.read(FILE); // 読み込み
    for (String[] strArray : read) {
      // totalの計算
      total_a += Double.valueOf(strArray[0]);
      total_b += Double.valueOf(strArray[1]);
      total_c += Double.valueOf(strArray[2]);
    }
    System.out.println(
        "\na:" + (total_a / SIM_NUM) + "\nb:" + (total_b / SIM_NUM) + "\nc:" + (total_c / SIM_NUM));
    System.out.println(((total_a / SIM_NUM) + (total_b / SIM_NUM) + (total_c / SIM_NUM)) / 3);
  }
  /**
   * 相手の大きい所に渡しあう
   *
   * @param a
   * @param b
   * @param c
   */
  private void exchangeRoleBigger(MiniAgent a, MiniAgent b, MiniAgent c) {
    ArrayList<Role> rl_a = a.getBiggerRoleList(); // aの降順ロールリスト
    ArrayList<Role> rl_b = b.getBiggerRoleList(); // bの降順ロールリスト
    ArrayList<Role> rl_c = c.getBiggerRoleList(); // cの降順ロールリスト

    // 1体目の交換
    Role roleBtoA = getEqualRole(rl_b, rl_a.get(0)); // bからaへ渡すロールを取得
    Role roleCtoA = getEqualRole(rl_c, rl_a.get(0)); // cからaへ渡すロールを取得
    a.receiveRoleVolume(roleBtoA, b.giveRoleVolume(roleBtoA)); // bからaにボリュームを渡す
    a.receiveRoleVolume(roleCtoA, c.giveRoleVolume(roleCtoA)); // cからaにボリュームを渡す

    // 2体目の交換
    Role roleAtoB = getEqualRole(rl_a, rl_b.get(0)); // aからbへ渡すロールを取得
    Role roleCtoB = getEqualRole(rl_c, rl_b.get(0)); // cからbへ渡すロールを取得
    // aに関する交換
    if (roleAtoB.equals(roleBtoA)) {
      roleAtoB = getEqualRole(rl_a, rl_b.get(1)); // すでに渡しているロールならば次のロールを渡す
    }
    // cに関する交換
    if (roleCtoB.equals(roleCtoA)) {
      roleCtoB = getEqualRole(rl_c, rl_b.get(1));
    }

    // トータルロールコストが今の状態よりよくなるならば交換をする
    MiniAgent aClone = (MiniAgent) a.clone();
    MiniAgent bClone = (MiniAgent) b.clone();
    MiniAgent cClone = (MiniAgent) c.clone();

    bClone.receiveRoleVolume(roleAtoB, aClone.giveRoleVolume(roleAtoB));
    bClone.receiveRoleVolume(roleCtoA, cClone.giveRoleVolume(roleCtoA));

    if (b.getTotalRoleCost() > bClone.getTotalRoleCost()) {
      // ロールを受け取る
      b.receiveRoleVolume(roleAtoB, a.giveRoleVolume(roleAtoB));
      b.receiveRoleVolume(roleCtoB, c.giveRoleVolume(roleCtoB));
    } else {
      roleAtoB = null;
      roleCtoB = null;
    }

    // 3体目の交換
    Role roleAtoC = getEqualRole(rl_a, rl_c.get(0)); // aからcへ渡すロールを取得
    Role roleBtoC = getEqualRole(rl_b, rl_c.get(0)); // bからcへ渡すロールを取得
    if (roleAtoC != null) {
      if (roleAtoC.equals(roleCtoA)) { // cがaに渡したロールと等しかったら次のロールを渡す
        roleAtoC = getEqualRole(rl_a, rl_c.get(1));
        if (roleAtoB != null) {
          if (roleAtoC.equals((roleAtoB))) { // aがbに渡したロールと等しかったらさらに次のロールを渡す
            roleAtoC = getEqualRole(rl_a, rl_c.get(2));
          }
        }
      }
    }
    if (roleBtoC != null) {
      if (roleBtoC.equals(roleBtoA)) { // bがaに渡したロールと等しかったら次のロールを渡す
        roleBtoC = getEqualRole(rl_a, rl_c.get(1));
        if (roleCtoB != null) {
          if (roleBtoC.equals(roleCtoB)) { // cがbに渡したロールと等しかったらさらに次のロールを渡す
            roleBtoC = getEqualRole(rl_a, rl_c.get(2));
          }
        }
      }
    }

    // トータルロールコストが今の状態よりよくなるならば交換をする
    aClone = (MiniAgent) a.clone();
    bClone = (MiniAgent) b.clone();
    cClone = (MiniAgent) c.clone();
    cClone.receiveRoleVolume(roleAtoC, aClone.giveRoleVolume(roleAtoC));
    cClone.receiveRoleVolume(roleCtoA, aClone.giveRoleVolume(roleCtoA));

    if (c.getTotalRoleCost() > cClone.getTotalRoleCost()) {
      // ロールを受け取る
      c.receiveRoleVolume(roleAtoC, a.giveRoleVolume(roleAtoC));
      c.receiveRoleVolume(roleCtoA, a.giveRoleVolume(roleCtoA));
    }
  }