fork download
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <queue>
  5. #include <cmath>
  6. #include <cstdlib>
  7. #include <ctime>
  8. #include <iomanip>
  9. #include <functional>
  10. #include <locale>
  11.  
  12. using namespace std;
  13.  
  14. /* ================================================================
  15.   СТРУКТУРА ЗАЯВКИ
  16.   ================================================================ */
  17. struct Customer {
  18. double arrival_time;
  19. bool refused;
  20. double start_time;
  21. double service_time;
  22. double departure_time;
  23.  
  24. Customer(double arr = 0.0)
  25. : arrival_time(arr), refused(false),
  26. start_time(-1.0), service_time(-1.0), departure_time(-1.0) {}
  27. };
  28.  
  29.  
  30. /* ================================================================
  31.   ГЛОБАЛЬНЫЕ КОНСТАНТЫ И ПАРАМЕТРЫ ЗАДАЧИ
  32.   ================================================================ */
  33.  
  34. // Параметры системы
  35. const int N0 = 6; // начальное число каналов
  36. const int M = 4; // число мест в очереди
  37. const double LAMBDA = 81.0; // интенсивность поступления заявок
  38. const double MU = 7.0; // интенсивность обслуживания
  39. const int J_CHANGE = 600; // после этой заявки меняется число каналов
  40. const int K_NEW = 7; // новое число каналов
  41.  
  42. // Параметры моделирования
  43. const int NUM_ARRIVALS = 1000; // заявок в одной серии
  44. const int NUM_REPS = 100; // число серий
  45.  
  46.  
  47. /* ================================================================
  48.   ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
  49.   ================================================================ */
  50.  
  51. // Генератор экспоненциального распределения
  52. double get_exp(double rate)
  53. {
  54. double u = (double)rand() / (RAND_MAX + 1.0);
  55. return -log(1.0 - u) / rate;
  56. }
  57.  
  58. // Вычисление среднего и СКО
  59. void compute_mean_sko(const vector<double>& vals, double& mean, double& sko)
  60. {
  61. int n = (int)vals.size();
  62. if (n <= 1) {
  63. mean = 0.0;
  64. sko = 0.0;
  65. return;
  66. }
  67. mean = 0.0;
  68. for (int i = 0; i < n; ++i) mean += vals[i];
  69. mean /= n;
  70.  
  71. double sumsq = 0.0;
  72. for (int i = 0; i < n; ++i) {
  73. double d = vals[i] - mean;
  74. sumsq += d * d;
  75. }
  76. sko = sqrt(sumsq / (n - 1.0));
  77. }
  78.  
  79.  
  80. /* ================================================================
  81.   ОСНОВНАЯ ФУНКЦИЯ
  82.   ================================================================ */
  83. int main()
  84. {
  85. setlocale(LC_ALL, "RU");
  86. // Векторы результатов всех серий
  87. vector<double> served_counts;
  88. vector<double> rel_throughputs;
  89. vector<double> abs_throughputs;
  90. vector<double> avg_services;
  91. vector<double> avg_waits;
  92. vector<double> avg_busies;
  93. vector<double> avg_queuelens;
  94.  
  95. srand((unsigned)time(NULL));
  96.  
  97. for (int rep = 0; rep < NUM_REPS; ++rep)
  98. {
  99. srand((unsigned)time(NULL) + (unsigned)rep);
  100.  
  101. vector<Customer> customers; // теперь используем глобальную структуру
  102. customers.reserve(NUM_ARRIVALS);
  103.  
  104. double current_time = 0.0;
  105. double last_update_time = 0.0;
  106. double integral_busy = 0.0;
  107. double integral_queuelen = 0.0;
  108.  
  109. priority_queue<double, vector<double>, greater<double> > departure_times;
  110. queue<int> waiting_queue;
  111.  
  112. int current_n = N0;
  113. int arrival_count = 0;
  114. bool arrivals_done = false;
  115. double next_arrival = get_exp(LAMBDA);
  116.  
  117. while (true)
  118. {
  119. double next_event = 1e18;
  120. bool is_arrival = false;
  121.  
  122. if (!arrivals_done) {
  123. next_event = next_arrival;
  124. is_arrival = true;
  125. }
  126. if (!departure_times.empty()) {
  127. double nd = departure_times.top();
  128. if (nd < next_event) {
  129. next_event = nd;
  130. is_arrival = false;
  131. }
  132. }
  133. if (next_event > 1e17) break;
  134.  
  135. double delta = next_event - last_update_time;
  136. if (delta > 0.0) {
  137. int busy = (int)departure_times.size();
  138. int ql = (int)waiting_queue.size();
  139. integral_busy += busy * delta;
  140. integral_queuelen += ql * delta;
  141. }
  142.  
  143. last_update_time = next_event;
  144. current_time = next_event;
  145.  
  146. if (is_arrival)
  147. {
  148. arrival_count++;
  149. customers.push_back(Customer(current_time));
  150. int idx = (int)customers.size() - 1;
  151.  
  152. int busy = (int)departure_times.size();
  153. if (busy < current_n) {
  154. double serv = get_exp(MU);
  155. customers[idx].start_time = current_time;
  156. customers[idx].service_time = serv;
  157. customers[idx].departure_time = current_time + serv;
  158. departure_times.push(customers[idx].departure_time);
  159. }
  160. else if ((int)waiting_queue.size() < M) {
  161. waiting_queue.push(idx);
  162. }
  163. else {
  164. customers[idx].refused = true;
  165. }
  166.  
  167. if (arrival_count < NUM_ARRIVALS) {
  168. next_arrival = current_time + get_exp(LAMBDA);
  169. }
  170. else {
  171. arrivals_done = true;
  172. }
  173.  
  174. if (arrival_count == J_CHANGE) {
  175. current_n = K_NEW;
  176. while ((int)departure_times.size() < current_n && !waiting_queue.empty()) {
  177. int qidx = waiting_queue.front(); waiting_queue.pop();
  178. double serv = get_exp(MU);
  179. customers[qidx].start_time = current_time;
  180. customers[qidx].service_time = serv;
  181. customers[qidx].departure_time = current_time + serv;
  182. departure_times.push(customers[qidx].departure_time);
  183. }
  184. }
  185. }
  186. else
  187. {
  188. departure_times.pop();
  189. if (!waiting_queue.empty()) {
  190. int qidx = waiting_queue.front(); waiting_queue.pop();
  191. double serv = get_exp(MU);
  192. customers[qidx].start_time = current_time;
  193. customers[qidx].service_time = serv;
  194. customers[qidx].departure_time = current_time + serv;
  195. departure_times.push(customers[qidx].departure_time);
  196. }
  197. }
  198. }
  199.  
  200. // Обработка результатов серии
  201. double T = current_time;
  202. double avg_busy = (T > 0.0) ? integral_busy / T : 0.0;
  203. double avg_queue = (T > 0.0) ? integral_queuelen / T : 0.0;
  204.  
  205. double sum_wait = 0.0, sum_serv = 0.0;
  206. int num_served = 0;
  207. for (int i = 0; i < (int)customers.size(); ++i) {
  208. const Customer& c = customers[i];
  209. if (!c.refused) {
  210. sum_wait += c.start_time - c.arrival_time;
  211. sum_serv += c.service_time;
  212. num_served++;
  213. }
  214. }
  215.  
  216. double avg_wait = (NUM_ARRIVALS > 0) ? integral_queuelen / NUM_ARRIVALS : 0.0;
  217. double avg_serv = (num_served > 0) ? sum_serv / num_served : 0.0;
  218. double rel = (double)num_served / NUM_ARRIVALS;
  219. double abs_th = (T > 0.0) ? (double)num_served / T : 0.0;
  220.  
  221. served_counts.push_back((double)num_served);
  222. rel_throughputs.push_back(rel);
  223. abs_throughputs.push_back(abs_th);
  224. avg_services.push_back(avg_serv);
  225. avg_waits.push_back(avg_wait);
  226. avg_busies.push_back(avg_busy);
  227. avg_queuelens.push_back(avg_queue);
  228.  
  229. // Таблица для первой серии
  230. if (rep == 0) {
  231. ofstream table("table.txt");
  232. if (table.is_open()) {
  233. table << "Таблица моделирования для одной серии (1000 заявок)\n\n";
  234. table << setw(6) << "№"
  235. << setw(18) << "Время поступления"
  236. << setw(18) << "Начало обслуж."
  237. << setw(18) << "Окончание"
  238. << setw(15) << "Ожидание"
  239. << setw(15) << "Обслуживание"
  240. << " Статус\n";
  241. table << "-----------------------------------------------------------------------------------------------\n";
  242.  
  243. table << fixed << setprecision(6);
  244. for (int i = 0; i < (int)customers.size(); ++i) {
  245. const Customer& c = customers[i];
  246. table << setw(6) << (i + 1) << setw(18) << c.arrival_time;
  247. if (c.refused) {
  248. table << setw(18) << "-" << setw(18) << "-"
  249. << setw(15) << "-" << setw(15) << "-"
  250. << " Отказ\n";
  251. }
  252. else {
  253. double wait = c.start_time - c.arrival_time;
  254. table << setw(18) << c.start_time
  255. << setw(18) << c.departure_time
  256. << setw(15) << wait
  257. << setw(15) << c.service_time
  258. << " Обслужена\n";
  259. }
  260. }
  261. table.close();
  262. }
  263. }
  264. }
  265.  
  266. // Вычисление средних и СКО
  267. double m_served, s_served, m_rel, s_rel, m_abs, s_abs;
  268. double m_serv, s_serv, m_wait, s_wait, m_busy, s_busy, m_queue, s_queue;
  269.  
  270. compute_mean_sko(served_counts, m_served, s_served);
  271. compute_mean_sko(rel_throughputs, m_rel, s_rel);
  272. compute_mean_sko(abs_throughputs, m_abs, s_abs);
  273. compute_mean_sko(avg_services, m_serv, s_serv);
  274. compute_mean_sko(avg_waits, m_wait, s_wait);
  275. compute_mean_sko(avg_busies, m_busy, s_busy);
  276. compute_mean_sko(avg_queuelens, m_queue, s_queue);
  277.  
  278. // Запись в output.txt
  279. ofstream out("output.txt");
  280. if (out.is_open()) {
  281. out << "Средние значения и среднеквадратические отклонения\n";
  282. out << "(100 серий по 1000 заявок каждая)\n\n";
  283. out << fixed << setprecision(6);
  284.  
  285. out << setw(45) << left << "Характеристика"
  286. << setw(18) << "Среднее"
  287. << setw(18) << "СКО" << "\n";
  288. out << "--------------------------------------------------------------------------------\n";
  289.  
  290. out << setw(45) << left << "Число обслуженных заявок"
  291. << setw(18) << m_served
  292. << setw(18) << s_served << "\n";
  293.  
  294. out << setw(45) << left << "Относительная пропускная способность"
  295. << setw(18) << m_rel
  296. << setw(18) << s_rel << "\n";
  297.  
  298. out << setw(45) << left << "Абсолютная пропускная способность"
  299. << setw(18) << m_abs
  300. << setw(18) << s_abs << "\n";
  301.  
  302. out << setw(45) << left << "Среднее время обслуживания"
  303. << setw(18) << m_serv
  304. << setw(18) << s_serv << "\n";
  305.  
  306. out << setw(45) << left << "Среднее время нахождения в очереди"
  307. << setw(18) << m_wait
  308. << setw(18) << s_wait << "\n";
  309.  
  310. out << setw(45) << left << "Среднее число занятых каналов"
  311. << setw(18) << m_busy
  312. << setw(18) << s_busy << "\n";
  313.  
  314. out << setw(45) << left << "Среднее число занятых мест в очереди"
  315. << setw(18) << m_queue
  316. << setw(18) << s_queue << "\n";
  317.  
  318. out.close();
  319. }
  320.  
  321. cout << "Симуляция завершена успешно!\n";
  322. cout << "Созданы файлы: output.txt и table.txt\n";
  323.  
  324. return 0;
  325. }
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
Симуляция завершена успешно!
Созданы файлы: output.txt и table.txt