Advertisement
Guest User

Untitled

a guest
Jun 18th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.63 KB | None | 0 0
  1. (0, 1, 0, 1, 1)
  2. (1, 1, 0, 1, 1)
  3. (1, 0, 0, 0, 1)
  4. (1, 1, 0, 1, 1)
  5. (1, 0, 0, 1, 0)
  6.  
  7. (0, 1, x, 1, 1)
  8. (1, 1, x, 1, 1)
  9. (1, 0, x, 0, 1)
  10. (1, 1, x, 1, 1)
  11. (1, 0, x, 1, 0)
  12.  
  13. (0, x, x, 1, 1)
  14. (1, x, x, 1, 1)
  15. (1, x, x, 0, 1)
  16. (1, x, x, 1, 1)
  17. (1, x, x, 1, 0)
  18.  
  19. (x, x, x, x, x)
  20. (1, 1, x, 1, 1)
  21. (x, x, x, x, x)
  22. (1, 1, x, 1, 1)
  23. (x, x, x, x, x)
  24.  
  25. public class Hungarian {
  26. public static void main(String[] args) {
  27. // m1 input values
  28. int[][] m1 = { { 0, 1, 0, 1, 1 }, { 1, 1, 0, 1, 1 }, { 1, 0, 0, 0, 1 },
  29. { 1, 1, 0, 1, 1 }, { 1, 0, 0, 1, 0 } };
  30.  
  31. // int[][] m1 = { {13,14,0,8},
  32. // {40,0,12,40},
  33. // {6,64,0,66},
  34. // {0,1,90,0}};
  35.  
  36. // int[][] m1 = { {0,0,100},
  37. // {50,100,0},
  38. // {0,50,50}};
  39.  
  40. // m2 max(horizontal,vertical) values, with negative number for
  41. // horizontal, positive for vertical
  42. int[][] m2 = new int[m1.length][m1.length];
  43.  
  44. // m3 where the line are drawen
  45. int[][] m3 = new int[m1.length][m1.length];
  46.  
  47. // loop on zeroes from the input array, and sotre the max num of zeroes
  48. // in the m2 array
  49. for (int row = 0; row < m1.length; row++) {
  50. for (int col = 0; col < m1.length; col++) {
  51. if (m1[row][col] == 0)
  52. m2[row][col] = hvMax(m1, row, col);
  53. }
  54. }
  55.  
  56. // print m1 array (Given input array)
  57. System.out.println("Given input array");
  58. for (int row = 0; row < m1.length; row++) {
  59. for (int col = 0; col < m1.length; col++) {
  60. System.out.print(m1[row][col] + "t");
  61. }
  62. System.out.println();
  63. }
  64.  
  65. // print m2 array
  66. System.out
  67. .println("nm2 array (max num of zeroes from horizontal vs vertical) (- for horizontal and + for vertical)");
  68. for (int row = 0; row < m1.length; row++) {
  69. for (int col = 0; col < m1.length; col++) {
  70. System.out.print(m2[row][col] + "t");
  71. }
  72. System.out.println();
  73. }
  74.  
  75. // Loop on m2 elements, clear neighbours and draw the lines
  76. for (int row = 0; row < m1.length; row++) {
  77. for (int col = 0; col < m1.length; col++) {
  78. if (Math.abs(m2[row][col]) > 0) {
  79. clearNeighbours(m2, m3, row, col);
  80. }
  81. }
  82. }
  83.  
  84. // prinit m3 array (Lines array)
  85. System.out.println("nLines array");
  86. for (int row = 0; row < m1.length; row++) {
  87. for (int col = 0; col < m1.length; col++) {
  88. System.out.print(m3[row][col] + "t");
  89. }
  90. System.out.println();
  91. }
  92. }
  93.  
  94. // max of vertical vs horizontal at index row col
  95. public static int hvMax(int[][] m1, int row, int col) {
  96. int vertical = 0;
  97. int horizontal = 0;
  98.  
  99. // check horizontal
  100. for (int i = 0; i < m1.length; i++) {
  101. if (m1[row][i] == 0)
  102. horizontal++;
  103. }
  104.  
  105. // check vertical
  106. for (int i = 0; i < m1.length; i++) {
  107. if (m1[i][col] == 0)
  108. vertical++;
  109. }
  110.  
  111. // negative for horizontal, positive for vertical
  112. return vertical > horizontal ? vertical : horizontal * -1;
  113. }
  114.  
  115. // clear the neighbors of the picked largest value, the sign will let the
  116. // app decide which direction to clear
  117. public static void clearNeighbours(int[][] m2, int[][] m3, int row, int col) {
  118. // if vertical
  119. if (m2[row][col] > 0) {
  120. for (int i = 0; i < m2.length; i++) {
  121. if (m2[i][col] > 0)
  122. m2[i][col] = 0; // clear neigbor
  123. m3[i][col] = 1; // draw line
  124. }
  125. } else {
  126. for (int i = 0; i < m2.length; i++) {
  127. if (m2[row][i] < 0)
  128. m2[row][i] = 0; // clear neigbor
  129. m3[row][i] = 1; // draw line
  130. }
  131. }
  132.  
  133. m2[row][col] = 0;
  134. m3[row][col] = 1;
  135. }
  136. }
  137.  
  138. Given input array
  139. 0 1 0 1 1
  140. 1 1 0 1 1
  141. 1 0 0 0 1
  142. 1 1 0 1 1
  143. 1 0 0 1 0
  144.  
  145. m2 array (max num of zeroes from horizontal vs vertical) (- for horizontal and + for vertical)
  146. -2 0 5 0 0
  147. 0 0 5 0 0
  148. 0 -3 5 -3 0
  149. 0 0 5 0 0
  150. 0 -3 5 0 -3
  151.  
  152. Lines array
  153. 1 1 1 1 1
  154. 0 0 1 0 0
  155. 1 1 1 1 1
  156. 0 0 1 0 0
  157. 1 1 1 1 1
  158.  
  159. 0 0 1
  160.  
  161. 0 1 1
  162.  
  163. 1 0 1
  164.  
  165. -2 -2 0
  166.  
  167. 2 0 0
  168.  
  169. 0 2 0
  170.  
  171. 0 1 1
  172.  
  173. 1 0 1
  174.  
  175. 0 0 1
  176.  
  177. 0 0 1 1 1
  178. 0 1 0 1 1
  179. 0 1 1 0 1
  180. 1 1 0 0 1
  181. 1 1 1 1 1
  182.  
  183. 3 -2 0 0 0
  184. 3 0 -2 0 0
  185. 3 0 0 -2 0
  186. 0 0 -2 -2 0
  187. 0 0 0 0 0
  188.  
  189. 3 -2 0 0 0
  190. 3 0 0 0 0
  191. 3 0 0 0 0
  192. 0 0 0 0 0
  193. 0 0 0 0 0
  194.  
  195. 1 1 1 1 1
  196. 1 1 0 1 1
  197. 1 1 1 0 1
  198. 1 1 0 0 1
  199. 1 1 1 1 1
  200.  
  201. 0 0 0 0 0
  202. 0 0 2 0 0
  203. 0 0 0 2 0
  204. 0 0 0 0 0
  205. 0 0 0 0 0
  206.  
  207. 0 0 1 1
  208. 0 1 1 1
  209. 1 0 1 1
  210. 1 1 1 0
  211.  
  212. 0 0 1 1 1
  213. 0 1 1 1 1
  214. 1 0 1 1 1
  215. 1 1 1 0 0
  216. 1 1 1 0 0
  217.  
  218. function [Lines, AllRows, AllCols] = FindMinLines(InMat)
  219.  
  220. %The following code finds the minimum set of lines (rows and columns)
  221. %required to cover all of the true-valued cells in a matrix. If using for
  222. %the Hungarian problem where 'true-values' are equal to zero, make the
  223. %necessary changes. This code is not complete, since it will be caught in
  224. %an infinite loop in the case of disjoint-tied-sets
  225.  
  226. %If passing in a matrix where 0s are the cells of interest, uncomment the
  227. %next line
  228. %InMat = InMat == 0;
  229.  
  230. %Assume square matrix
  231. Count = length(InMat);
  232. Lines = zeros(Count);
  233.  
  234. %while there are any 'true' values not covered by lines
  235.  
  236. while any(any(~Lines & InMat))
  237. %Calculate row-wise and col-wise totals of 'trues' not-already-covered
  238. HorzCount = repmat(sum(~Lines & InMat, 2), 1, Count).*(~Lines & InMat);
  239. VertCount = repmat(sum(~Lines & InMat, 1), Count, 1).*(~Lines & InMat);
  240.  
  241. %Calculate for each cell the difference between row-wise and col-wise
  242. %counts. I.e. row-oriented cells will have a negative number, col-oriented
  243. %cells will have a positive numbers, ties and 'non-trues' will be 0.
  244. %Non-zero values indicate lines to be drawn where orientation is determined
  245. %by sign.
  246. DiffCounts = VertCount - HorzCount;
  247.  
  248. %find the row and col indices of the lines
  249. HorzIdx = any(DiffCounts < 0, 2);
  250. VertIdx = any(DiffCounts > 0, 1);
  251.  
  252. %Set the horizontal and vertical indices of the Lines matrix to true
  253. Lines(HorzIdx, :) = true;
  254. Lines(:, VertIdx) = true;
  255. end
  256.  
  257. %compute index numbers to be returned.
  258. AllRows = [find(HorzIdx); find(DisjTiedRows)];
  259. AllCols = find(VertIdx);
  260.  
  261. end
  262.  
  263. horizontal line (row): {"0":0,"2":2,"4":4}
  264. vertical line (column): {"2":2}
  265.  
  266. Step 5: Matrix
  267. 0 1 0 1 1
  268. 1 1 0 1 1
  269. 1 0 0 0 1
  270. 1 1 0 1 1
  271. 1 0 0 1 0
  272.  
  273. Smallest number in uncovered matrix: 1
  274. Step 6: Matrix
  275. x x x x x
  276. 1 1 x 1 1
  277. x x x x x
  278. 1 1 x 1 1
  279. x x x x x
  280.  
  281. def draw_lines grid
  282. #copies the array
  283. marking_grid = grid.map { |a| a.dup }
  284.  
  285. marked_rows = Array.new
  286. marked_cols = Array.new
  287.  
  288. while there_is_zero(marking_grid) do
  289. marking_grid = grid.map { |a| a.dup }
  290.  
  291. marked_cols.each do |col|
  292. cross_out(marking_grid,nil, col)
  293. end
  294.  
  295. marked = assignment(grid, marking_grid)
  296. marked_rows = marked[0]
  297. marked_cols.concat(marked[1]).uniq!
  298.  
  299. marking_grid = grid.map { |a| a.dup }
  300.  
  301. marking_grid.length.times do |row|
  302. if !(marked_rows.include? row) then
  303. cross_out(marking_grid,row, nil)
  304. end
  305. end
  306.  
  307. marked_cols.each do |col|
  308. cross_out(marking_grid,nil, col)
  309. end
  310.  
  311. end
  312.  
  313.  
  314. lines = Array.new
  315.  
  316. marked_cols.each do |index|
  317. lines.push(["column", index])
  318. end
  319. grid.each_index do |index|
  320. if !(marked_rows.include? index) then
  321. lines.push(["row", index])
  322. end
  323. end
  324. return lines
  325. end
  326.  
  327.  
  328. def there_is_zero grid
  329. grid.each_with_index do |row|
  330. row.each_with_index do |value|
  331. if value == 0 then
  332. return true
  333. end
  334. end
  335. end
  336. return false
  337. end
  338.  
  339. def assignment grid, marking_grid
  340. marking_grid.each_index do |row_index|
  341. first_zero = marking_grid[row_index].index(0)
  342. #if there is no zero go to next row
  343. if first_zero.nil? then
  344. next
  345. else
  346. cross_out(marking_grid, row_index, first_zero)
  347. marking_grid[row_index][first_zero] = "*"
  348. end
  349. end
  350.  
  351. return mark(grid, marking_grid)
  352. end
  353.  
  354.  
  355. def mark grid, marking_grid, marked_rows = Array.new, marked_cols = Array.new
  356. marking_grid.each_with_index do |row, row_index|
  357. selected_assignment = row.index("*")
  358. if selected_assignment.nil? then
  359. marked_rows.push(row_index)
  360. end
  361. end
  362.  
  363. marked_rows.each do |index|
  364. grid[index].each_with_index do |cost, col_index|
  365. if cost == 0 then
  366. marked_cols.push(col_index)
  367. end
  368. end
  369. end
  370. marked_cols = marked_cols.uniq
  371.  
  372. marked_cols.each do |col_index|
  373. marking_grid.each_with_index do |row, row_index|
  374. if row[col_index] == "*" then
  375. marked_rows.push(row_index)
  376. end
  377. end
  378. end
  379.  
  380. return [marked_rows, marked_cols]
  381. end
  382.  
  383.  
  384. def cross_out(marking_grid, row, col)
  385. if col != nil then
  386. marking_grid.each_index do |i|
  387. marking_grid[i][col] = "X"
  388. end
  389. end
  390. if row != nil then
  391. marking_grid[row].map! {|i| "X"}
  392. end
  393. end
  394.  
  395. grid = [
  396. [0,0,1,0],
  397. [0,0,1,0],
  398. [0,1,1,1],
  399. [0,1,1,1],
  400. ]
  401.  
  402. p draw_lines(grid)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement