Guest User

RAIC 2012 optimizer

a guest
Nov 24th, 2012
1,923
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.47 KB | None | 0 0
  1. #include <map>
  2. #include <cmath>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <fstream>
  6. #include <iostream>
  7. #include <sys/wait.h>
  8. #include <sys/types.h>
  9. #include <unistd.h>
  10. #include <signal.h>
  11.  
  12. using namespace std;
  13.  
  14.  
  15. ofstream log_file("log.txt", ios::app);
  16. //#define log_file cout
  17.  
  18.  
  19. enum ValType
  20. {
  21.     vt_01, vt_log
  22. };
  23.  
  24. struct Param
  25. {
  26.     double init_val;
  27.     ValType type;
  28. };
  29.  
  30. const Param param[] =
  31. {
  32.     {0.4, vt_01}, {0.3, vt_01}, {0.1, vt_01},
  33.     {2.5, vt_log}, {0.4, vt_log}, {0.2, vt_log},
  34.     {30, vt_log}, {50, vt_log}, {10, vt_log},
  35.     {600, vt_log}, {0.1, vt_log}, {0.07, vt_log}, {0.8, vt_log},
  36.     {3, vt_log}, {2, vt_log}, {0.5, vt_01},
  37.     {1.2, vt_log}, {30000, vt_log},
  38.     {0.08, vt_log}, {250, vt_log},
  39.     {6, vt_log}, {100, vt_log},
  40.     {0.5, vt_log}, {4000, vt_log}
  41. };
  42.  
  43. const int param_count = sizeof(param) / sizeof(Param);
  44.  
  45.  
  46. double mirror(double val)
  47. {
  48.     if(val < 0)return -val;  if(val > 1)return 2 - val;  return val;
  49. }
  50.  
  51. double rand_move()
  52. {
  53.     double res = random() / (0.5 * RAND_MAX) - 1;
  54.     return res * res * res * abs(res);
  55. }
  56.  
  57. struct State
  58. {
  59.     static int next_id;
  60.  
  61.     int id, score;
  62.     double val[param_count];
  63.  
  64.     void init()
  65.     {
  66.         id = 0;
  67.         for(int i = 0; i < param_count; i++)val[i] = param[i].init_val;
  68.     }
  69.  
  70.     void mutate(const State &parent)
  71.     {
  72.         id = next_id++;
  73.         for(int i = 0; i < param_count; i++)
  74.             if(param[i].type == vt_01)val[i] = mirror(parent.val[i] + rand_move());
  75.             else val[i] = parent.val[i] * exp(rand_move());
  76.     }
  77.  
  78.     void print(const char *title = "New ")
  79.     {
  80.         log_file << title << id << ':';
  81.         for(int i = 0; i < param_count; i++)log_file << ' ' << val[i];
  82.         log_file << endl;
  83.     }
  84.  
  85.     bool load(istream &file)
  86.     {
  87.         unsigned long long num;
  88.         file.read(reinterpret_cast<char *>(&num), sizeof(num));  id = num;
  89.         file.read(reinterpret_cast<char *>(val), sizeof(val));  return file;
  90.     }
  91.  
  92.     bool save(ostream &file) const
  93.     {
  94.         unsigned long long num = id;
  95.         file.write(reinterpret_cast<char *>(&num), sizeof(num));
  96.         file.write(reinterpret_cast<const char *>(val), sizeof(val));  return file;
  97.     }
  98. };
  99.  
  100. int State::next_id = 1;
  101.  
  102.  
  103. pid_t start_strategy(const State &state, int port)
  104. {
  105.     int pfd[2];
  106.     if(pipe(pfd))
  107.     {
  108.         cout << "Cannot create pipe!" << endl;  return -1;
  109.     }
  110.  
  111.     pid_t pid = fork();
  112.     if(!pid)
  113.     {
  114.         close(STDIN_FILENO);
  115.         if(dup2(pfd[0], STDIN_FILENO) != STDIN_FILENO)exit(-1);
  116.         close(pfd[0]);  close(pfd[1]);
  117.  
  118.         char buf[8];  sprintf(buf, "%d", port);
  119.         execl("MyStrategy", "MyStrategy", "localhost", buf, "0000000000000000", static_cast<char *>(0));
  120.         printf("Cannot start strategy!\n");  exit(-1);
  121.     }
  122.     if(pid == -1)
  123.     {
  124.         close(pfd[0]);  close(pfd[1]);
  125.         cout << "Cannot create process!" << endl;  return -1;
  126.     }
  127.  
  128.     static const unsigned long long flag = 0x0123456789ABCDEF;
  129.  
  130.     close(pfd[0]);
  131.     if(write(pfd[1], &flag, sizeof(flag)) != sizeof(flag) ||
  132.         write(pfd[1], state.val, sizeof(state.val)) != sizeof(state.val) ||
  133.         write(pfd[1], &flag, sizeof(flag)) != sizeof(flag))
  134.     {
  135.         kill(pid, SIGKILL);  close(pfd[1]);
  136.         cout << "Cannot send parameters!" << endl;  return -1;
  137.     }
  138.     close(pfd[1]);  return pid;
  139. }
  140.  
  141.  
  142. struct Game
  143. {
  144.     static const int player_count = 2;
  145.  
  146.     static int next_id;
  147.  
  148.     int id;
  149.     State *state[player_count];
  150.  
  151.     Game()
  152.     {
  153.     }
  154.  
  155.     Game(State &state1, State &state2) : id(next_id++)
  156.     {
  157.         state[0] = &state1;  state[1] = &state2;
  158.     }
  159.  
  160.     bool process_result()
  161.     {
  162.         static const int place_score[] = {1, 0};
  163.  
  164.         char buf[256];  sprintf(buf, "games/%06d.txt", id);
  165.         ifstream res_file(buf);  string text;  res_file >> text;
  166.         if(text != "OK")
  167.         {
  168.             cout << "Game " << id << " failed!" << endl;  return false;
  169.         }
  170.  
  171.         int top[player_count];
  172.         for(int i = 0; i < player_count; i++)top[i] = -1;
  173.  
  174.         for(int i = 0; i < player_count; i++)
  175.         {
  176.             int place, score;
  177.             res_file >> place >> score >> text;
  178.             for(place--;; place++)
  179.             {
  180.                 if(place < 0 || place >= player_count)
  181.                 {
  182.                     cout << "Game " << id << ": invalid result!" << endl;  return false;
  183.                 }
  184.                 if(top[place] < 0)break;
  185.             }
  186.             top[place] = i;  state[i]->score += place_score[place];
  187.         }
  188.  
  189.         log_file << "Game " << id << ':';
  190.         for(int i = 0; i < player_count; i++)log_file << ' ' << state[top[i]]->id;
  191.         log_file << endl;  return true;
  192.     }
  193. };
  194.  
  195. int Game::next_id = 0;
  196.  
  197.  
  198. pid_t start_game(const Game &game, int base_port)
  199. {
  200.     pid_t pid = fork();
  201.     if(!pid)
  202.     {
  203.         char buf1[256], buf2[256];
  204.         sprintf(buf1, "-base-adapter-port=%d", base_port);
  205.         sprintf(buf2, "-results-file=games/%06d.txt", game.id);
  206.         execl("/usr/bin/java", "java", "-cp", ".:local-runner.jar", "Run", "-render-to-screen=false",
  207.             //"-render-to-screen=true", "-render-to-screen-scale=0.75", "-render-to-screen-sync=true",
  208.             "-debug=true", buf1, "-p1-name=P1", "-p1-team-size=3", "-p2-name=P2", "-p2-team-size=3",
  209.             buf2, "#LocalTestPlayer", "#LocalTestPlayer", static_cast<char *>(0));
  210.         printf("Cannot start game!\n");  exit(-1);
  211.     }
  212.     if(pid == -1)
  213.     {
  214.         cout << "Cannot create process!" << endl;  return -1;
  215.     }
  216.     usleep(1000000);
  217.  
  218.     for(int i = 0; i < Game::player_count; i++)
  219.     {
  220.         usleep(200000);
  221.         start_strategy(*game.state[i], base_port + i);
  222.     }
  223.     return pid;
  224. }
  225.  
  226.  
  227. const int state_count = 8;
  228. const unsigned long long header = 0x0123456789ABCDEF ^ (state_count << 16 | param_count);
  229.  
  230. bool load(State state[state_count])
  231. {
  232.     ifstream file("restart.dat");  unsigned long long num = 0;
  233.     file.read(reinterpret_cast<char *>(&num), sizeof(num));
  234.     if(num != header)return false;
  235.     file.read(reinterpret_cast<char *>(&num), sizeof(num));
  236.     State::next_id = num >> 32;  Game::next_id = num & 0xFFFFFFFF;
  237.     for(int i = 0; i < state_count; i++)if(!state[i].load(file))return false;
  238.     return true;
  239. }
  240.  
  241. bool save(State state[state_count])
  242. {
  243.     ofstream file("restart.dat", ios::trunc);
  244.     file.write(reinterpret_cast<const char *>(&header), sizeof(header));
  245.     unsigned long long num = (unsigned long long)State::next_id << 32 | Game::next_id;
  246.     file.write(reinterpret_cast<char *>(&num), sizeof(num));
  247.     for(int i = 0; i < state_count; i++)if(!state[i].save(file))return false;
  248.     return true;
  249. }
  250.  
  251. bool round(State state[state_count])
  252. {
  253.     static const int game_count = 6;
  254.  
  255.     for(int i = 0; i < state_count; i++)state[i].score = 0;
  256.  
  257.     map<pid_t, Game> games;
  258.     int ip1 = 0, ip2 = 1, port = 31000;
  259.     while(ip2 < state_count || games.size())
  260.     {
  261.         while(ip2 < state_count && games.size() < game_count)
  262.         {
  263.             Game game(state[ip1], state[ip2]);
  264.             pid_t pid = start_game(game, port);
  265.             if(pid < 0)return false;
  266.  
  267.             games[pid] = game;  port += Game::player_count;
  268.             if(++ip2 >= state_count)
  269.             {
  270.                 ip2 = ++ip1 + 1;
  271.                 if(ip2 >= state_count)break;
  272.             }
  273.         }
  274.  
  275.         pid_t pid = waitpid(0, 0, 0);
  276.         map<pid_t, Game>::iterator ptr = games.find(pid);
  277.         if(ptr != games.end())
  278.         {
  279.             if(!ptr->second.process_result())return false;  games.erase(ptr);
  280.         }
  281.     }
  282.  
  283.     int best = 0, worst = 0;
  284.     for(int i = 1; i < state_count; i++)
  285.     {
  286.         if(state[i].score > state[best].score)best = i;
  287.         if(state[i].score < state[worst].score)worst = i;
  288.     }
  289.     log_file << "End round, worst " << state[worst].id << " removed" << endl;
  290.     state[best].print("Best ");  state[worst].mutate(state[best]);
  291.     state[worst].print();  log_file << endl;  save(state);  return true;
  292. }
  293.  
  294. int main()
  295. {
  296.     State state[state_count];
  297.     if(load(state))log_file << "Loaded restart file:" << endl;
  298.     else
  299.     {
  300.         log_file << "Cannot find restart file, generating:" << endl;
  301.  
  302.         state[0].init();
  303.         for(int i = 1; i < state_count; i++)state[i].mutate(state[0]);
  304.         save(state);
  305.     }
  306.     for(int i = 0; i < state_count; i++)state[i].print();  log_file << endl;
  307.     while(round(state));
  308. }
Advertisement
Add Comment
Please, Sign In to add comment