Advertisement
Guest User

Untitled

a guest
May 22nd, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.98 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <fstream>
  5. #include <string>
  6. using namespace std;
  7. const int INF = 1e9;
  8. int n, **a;
  9. void read()
  10. {
  11. cout << "Введите N:";
  12. cin >> n;
  13. a = new int*[n+1];
  14.  
  15.  
  16. for (int i = 0; i<=n; i++)
  17. {
  18. a[i] = new int[n+1];
  19. for (int j = 0; j<=n; j++)
  20. a[i][j] = 0;
  21. }
  22. cout << "Введите матрицу заработных плат NxN:";
  23. for (int i = 1; i<=n; i++)
  24. for (int j = 1; j<=n; j++)
  25. cin >> a[i][j];
  26.  
  27.  
  28. }
  29. bool readfromfile()
  30. {
  31. cout << "Введите путь к файлу: ";
  32. string s;
  33. cin >> s;
  34. ifstream fin(s);
  35. if (!(fin >> n))
  36. return false;
  37. a = new int*[n+1];
  38.  
  39.  
  40. for (int i = 0; i<=n; i++)
  41. {
  42. a[i] = new int[n+1];
  43. for (int j = 0; j<=n; j++)
  44. a[i][j] = 0;
  45. }
  46.  
  47. for (int i = 1; i<=n; i++)
  48. for (int j = 1; j<=n; j++)
  49. if (!(fin >> a[i][j]))
  50. return false;
  51.  
  52. return true;
  53. }
  54. int Hungop;
  55. vector<int> HungarianAlgo(int n, int **a)
  56. {
  57. int m = n;
  58. vector<int> u (n+1), v (m+1), p (m+1), way (m+1);
  59. Hungop+=n+1;
  60. Hungop+=m+1;
  61. Hungop+=m+1;
  62. Hungop+=m+1;
  63. for (int i=1; i<=n; ++i)
  64. {
  65. p[0] = i;
  66. Hungop++;
  67. int j0 = 0;
  68. Hungop++;
  69. vector<int> minv (m+1, INF);
  70. Hungop+=m+1;
  71. vector<char> used (m+1, false);
  72. Hungop+=m+1;
  73. do {
  74. used[j0] = true;
  75. Hungop++;
  76. int i0 = p[j0], delta = INF, j1 = 0;
  77. Hungop+=3;
  78. for (int j=1; j<=m; ++j)
  79. {
  80. Hungop++;
  81. if (!used[j]) {
  82. int cur = a[i0][j]-u[i0]-v[j];
  83. Hungop+=2;
  84. Hungop++;
  85. if (cur < minv[j])
  86. {
  87. minv[j] = cur, way[j] = j0;
  88. Hungop+=2;
  89. }
  90. Hungop++;
  91. if (minv[j] < delta)
  92. {
  93. Hungop+=2;
  94. delta = minv[j], j1 = j;
  95. }
  96. }
  97. }
  98. for (int j=0; j<=m; ++j)
  99. {
  100. Hungop++;
  101. if (used[j])
  102. {
  103. Hungop+=2;
  104. u[p[j]] += delta, v[j] -= delta;
  105. }
  106. else
  107. {
  108. Hungop++;
  109. minv[j] -= delta;
  110. }
  111. }
  112. j0 = j1;
  113. Hungop++;
  114. }
  115. while (p[j0] != 0);
  116. do {
  117. int j1 = way[j0];
  118. p[j0] = p[j1];
  119. j0 = j1;
  120. Hungop+=3;
  121. } while (j0);
  122. }
  123. vector<int> ans (n+1);
  124. Hungop+=n+1;
  125. for (int j=1; j<=m; ++j)
  126. ans[p[j]] = j;
  127. Hungop+=m;
  128. return ans;
  129. }
  130.  
  131. int MincostOp;
  132.  
  133. struct edge
  134. {
  135. int to, cap,cost,flow; // куда идет ребро, пропускная способность, стоимость, величина потока
  136. size_t back; // откуда пришло ребро
  137. };
  138.  
  139. void add_edge(vector<vector<edge>> &g, int from , int to, int cap, int cost)
  140. {
  141. //cout << "from: " <<from << " to: " <<to << " cap: " << cap << " cost: "<< cost << endl;
  142.  
  143. MincostOp+=5;
  144. edge e1 = {to,cap,cost,0,g[to].size()};
  145.  
  146. MincostOp+=5;
  147. edge e2 = {from,0,-cost,0, g[from].size()};
  148. g[from].push_back(e1);
  149. g[to].push_back(e2);
  150.  
  151. MincostOp+=2;
  152.  
  153. }
  154. vector<int> mincostmaxflow(int sz, int **a)
  155. {
  156. int s = 0; // исток
  157. int t = sz+sz+1;// сток
  158. int nn = t+1;
  159. MincostOp+=3;
  160. vector<vector<edge>> g(nn);
  161. MincostOp+=nn;
  162.  
  163. // добавили ребра из истока в работников
  164. // добавили ребра из задач в сток
  165. MincostOp+=sz;
  166. for (int i = 1; i<=sz; i++)
  167. {
  168.  
  169. add_edge(g, s, i, 1, 0);
  170. add_edge(g, i+sz, t, 1, 0);
  171. }
  172. MincostOp+=sz*sz;
  173. for (int i = 1; i<=sz; i++)
  174. {
  175. for (int j = 1; j<=sz; j++)
  176. {
  177. add_edge(g, i, j+sz, 1, a[i][j]);
  178. }
  179. }
  180. int flow = 0, cost = 0;
  181. MincostOp+=2;
  182. while (flow<sz)
  183. {
  184. MincostOp++;
  185. vector<int> id(nn);
  186. vector<int> d(nn,INF);
  187. vector<int> q(nn);
  188. vector<int> p(nn);
  189.  
  190. vector<size_t> p_rib(nn);
  191.  
  192. MincostOp+=5*nn;
  193. int qh = 0, qt = 0;
  194. q[qt++] = s;
  195. d[s] = 0;
  196. MincostOp+=5;
  197. while (qh!=qt)
  198. {
  199. MincostOp+=2;
  200. int v = q[qh++];
  201. MincostOp++;
  202. id[v] = 2;
  203. MincostOp++;
  204. if (qh==nn)
  205. {
  206. MincostOp++;
  207. qh = 0;
  208. }
  209. for (int i = 0; i<g[v].size(); i++)
  210. {
  211. MincostOp++;
  212. edge &e = g[v][i];
  213. MincostOp+=3;
  214. if (e.flow < e.cap && d[v] + e.cost < d[e.to]) {
  215. MincostOp+=2;
  216. d[e.to] = d[v] + e.cost;
  217. MincostOp++;
  218. if (id[e.to] == 0) {
  219. MincostOp+=2;
  220. q[qt++] = e.to;
  221. MincostOp++;
  222. if (qt == nn)
  223. {
  224. MincostOp++;
  225. qt = 0;
  226. }
  227. }
  228. else if (id[e.to] == 2) {
  229. MincostOp++;
  230. if (--qh == -1)
  231. {
  232. MincostOp++;
  233. qh = nn-1;
  234. }
  235. MincostOp++;
  236. q[qh] = e.to;
  237. }
  238. id[e.to] = 1;
  239. p[e.to] = v;
  240. p_rib[e.to] = i;
  241. MincostOp+=3;
  242. }
  243. }
  244. }
  245. MincostOp++;
  246. if (d[t]==INF)
  247. break;
  248. MincostOp++;
  249. int addflow = sz-flow;
  250. for (int v=t; v!=s; v=p[v]) {
  251. MincostOp++;
  252. int pv = p[v];
  253. size_t pr = p_rib[v];
  254. MincostOp++;
  255. addflow = min (addflow, g[pv][pr].cap - g[pv][pr].flow);
  256. }
  257. for (int v=t; v!=s; v=p[v]) {
  258. MincostOp++;
  259. int pv = p[v];
  260. MincostOp+=2;
  261. size_t pr = p_rib[v], r = g[pv][pr].back;
  262. MincostOp++;
  263. g[pv][pr].flow += addflow;
  264. MincostOp++;
  265. g[v][r].flow -= addflow;
  266. MincostOp++;
  267. cost += g[pv][pr].cost * addflow;
  268. }
  269. MincostOp++;
  270. flow += addflow;
  271.  
  272. }
  273. vector<int> ans(sz+1);
  274. MincostOp+=sz+1;
  275. for (int i = 1; i<=sz; i++)
  276. {
  277. MincostOp++;
  278. for (int j = 0; j<g[i].size(); j++)
  279. {
  280. MincostOp++;
  281. if (g[i][j].flow==1)
  282. {
  283. MincostOp++;
  284. ans[i] = j;
  285. }
  286. }
  287. }
  288. return ans;
  289.  
  290. }
  291. void solve(ostream &cout)
  292. {
  293.  
  294. MincostOp= 0;
  295. Hungop = 0;
  296. // венгерский алгоритм
  297.  
  298. auto ans1 = HungarianAlgo(n, a);
  299. auto ans2 = mincostmaxflow(n, a);
  300.  
  301. int cost = 0;
  302. for (int i = 1; i<=n; i++)
  303. {
  304. cost +=a[i][ans1[i]];
  305. cout << ans1[i] << " ";
  306. }
  307.  
  308.  
  309. cout <<"Минимальные затраты: " << cost <<endl;
  310. cout << "Количество операций венгерского алгоритма: " << Hungop << "\n";
  311. cout << "Количество операций потокового алгоритма: " << MincostOp << "\n";
  312.  
  313.  
  314.  
  315. }
  316. int get_command()
  317. {
  318. int x = -1;
  319. while (x<0 || x>3)
  320. {
  321. cout << "Введите 1 для проведения иследование\n 2 для ввода данных с файла\n 3 для ввода данных вручную\n 0 для выхода\n";
  322. cin >> x;
  323. }
  324. return x;
  325. }
  326. void issledovanie()
  327. {
  328. int MAXTEST = 10; // это изменять чтоб увеличить количество тестов
  329. n = 25; //это изменять чтоб увеличить размер таблицы
  330. a = new int*[n+1];
  331. for (int i = 0; i<=n; i++)
  332. a[i] = new int[n+1];
  333. int mod = 10;
  334. ofstream cout("issledovanie.txt");
  335. for (int i = 0; i<MAXTEST; i++)
  336. {
  337. for (int j = 0; j<=n; j++)
  338. for (int k = 0; k<=n; k++)
  339. a[j][k] = 0;
  340. for (int j = 1; j<=n; j++)
  341. {
  342. for (int k = 1; k<=n; k++)
  343. {
  344. a[j][k] = rand()%mod+1;
  345. cout << a[j][k] << " "; // это закомментить чтоб не выводилась матрица в файл
  346. }
  347. cout << endl; //это закомментить чтоб не выводилась матрица в файл
  348. }
  349. solve(cout);
  350. }
  351. cout.close();
  352. }
  353. int main()
  354. {
  355.  
  356. while (true)
  357. {
  358. int x = get_command();
  359. if (x == 0)
  360. break;
  361. if (x == 1)
  362. {
  363. issledovanie();
  364. }
  365. else
  366. if (x == 2)
  367. {
  368. bool readed = readfromfile();
  369. if (!readed)
  370. {
  371. cout << "Неправильный путь или неверные входные данные в файле. Повторите еще раз";
  372. continue;
  373. }
  374. solve(cout);
  375. }
  376. else
  377. if (x == 3)
  378. {
  379. read();
  380. solve(cout);
  381. }
  382. }
  383. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement