PageRenderTime 60ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/testSchulze.cpp

https://bitbucket.org/capitol/schulze
C++ | 543 lines | 422 code | 103 blank | 18 comment | 48 complexity | a20ba5a3a1043e647ee63d3f22bd41dc MD5 | raw file
  1. /*
  2. libschulze, a library that implements the schulze voting algorithm
  3. Copyright (C) 2013 Alexander Kjäll
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "../src/candidate.h"
  16. #include "../src/ranking.h"
  17. #include "../src/schulze.h"
  18. #include <boost/test/unit_test.hpp>
  19. #include <list>
  20. #include <vector>
  21. BOOST_AUTO_TEST_CASE(CheckSchulzeEmptyInput) {
  22. Ranking rank1;
  23. std::vector<Candidate<int>> clist;
  24. std::list<Ranking> rlist = { rank1 };
  25. Schulze s;
  26. VoteResult expResult;
  27. VoteResult result = s.calc(rlist, clist);
  28. BOOST_CHECK_EQUAL(expResult, result);
  29. }
  30. BOOST_AUTO_TEST_CASE(CheckSchulzeTwoCandidatesTwoRanks) {
  31. Candidate<int> c1(0, 0, "c1"), c2(1, 1, "c2");
  32. Ranking rank1, rank2{ c1, c2 };
  33. rank1.setRank(c1, 1);
  34. rank1.setRank(c2, 1);
  35. std::vector<Candidate<int>> clist { c1, c2 };
  36. std::list<Ranking> rlist = { rank1, rank2 };
  37. Schulze s;
  38. VoteResult expResult { c1, c2 };
  39. VoteResult result = s.calc(rlist, clist);
  40. BOOST_CHECK_EQUAL(expResult, result);
  41. }
  42. void rankWikipedia(Ranking* ranks, Candidate<int>& cA, Candidate<int>& cB, Candidate<int>& cC, Candidate<int>& cD, Candidate<int>& cE) {
  43. int tot = 0;
  44. for(int i = 0; i < 5; i++, tot++) {
  45. ranks[tot].setRank(cA, 0);
  46. ranks[tot].setRank(cC, 1);
  47. ranks[tot].setRank(cB, 2);
  48. ranks[tot].setRank(cE, 3);
  49. ranks[tot].setRank(cD, 4);
  50. }
  51. for(int i = 0; i < 5; i++, tot++) {
  52. ranks[tot].setRank(cA, 0);
  53. ranks[tot].setRank(cD, 1);
  54. ranks[tot].setRank(cE, 2);
  55. ranks[tot].setRank(cC, 3);
  56. ranks[tot].setRank(cB, 4);
  57. }
  58. for(int i = 0; i < 8; i++, tot++) {
  59. ranks[tot].setRank(cB, 0);
  60. ranks[tot].setRank(cE, 1);
  61. ranks[tot].setRank(cD, 2);
  62. ranks[tot].setRank(cA, 3);
  63. ranks[tot].setRank(cC, 4);
  64. }
  65. for(int i = 0; i < 3; i++, tot++) {
  66. ranks[tot].setRank(cC, 0);
  67. ranks[tot].setRank(cA, 1);
  68. ranks[tot].setRank(cB, 2);
  69. ranks[tot].setRank(cE, 3);
  70. ranks[tot].setRank(cD, 4);
  71. }
  72. for(int i = 0; i < 7; i++, tot++) {
  73. ranks[tot].setRank(cC, 0);
  74. ranks[tot].setRank(cA, 1);
  75. ranks[tot].setRank(cE, 2);
  76. ranks[tot].setRank(cB, 3);
  77. ranks[tot].setRank(cD, 4);
  78. }
  79. for(int i = 0; i < 2; i++, tot++) {
  80. ranks[tot].setRank(cC, 0);
  81. ranks[tot].setRank(cB, 1);
  82. ranks[tot].setRank(cA, 2);
  83. ranks[tot].setRank(cD, 3);
  84. ranks[tot].setRank(cE, 4);
  85. }
  86. for(int i = 0; i < 7; i++, tot++) {
  87. ranks[tot].setRank(cD, 0);
  88. ranks[tot].setRank(cC, 1);
  89. ranks[tot].setRank(cE, 2);
  90. ranks[tot].setRank(cB, 3);
  91. ranks[tot].setRank(cA, 4);
  92. }
  93. for(int i = 0; i < 8; i++, tot++) {
  94. ranks[tot].setRank(cE, 0);
  95. ranks[tot].setRank(cB, 1);
  96. ranks[tot].setRank(cA, 2);
  97. ranks[tot].setRank(cD, 3);
  98. ranks[tot].setRank(cC, 4);
  99. }
  100. }
  101. BOOST_AUTO_TEST_CASE(CheckSchulzeWikipediaExample) {
  102. Candidate<int> cA(0, 0, "cA"), cB(1, 1, "cB"), cC(2, 2, "cC"), cD(3, 3, "cD"), cE(4, 4, "cE");
  103. Ranking ranks[45];
  104. rankWikipedia(ranks, cA, cB, cC, cD, cE);
  105. std::vector<Candidate<int>> clist { cA, cB, cC, cD, cE };
  106. std::list<Ranking> rlist(std::begin(ranks), std::end(ranks));
  107. Schulze s;
  108. VoteResult result = s.calc(rlist, clist);
  109. VoteResult expResult { cE, cA, cC, cB, cD };
  110. BOOST_CHECK_EQUAL(expResult, result);
  111. }
  112. BOOST_AUTO_TEST_CASE(CheckSchulzeWorkshopExample) {
  113. Candidate<int> cA(0, 0), cB(1, 1), cC(2, 2), cD(3, 3), cE(4, 4), cF(5, 5), cG(6, 6), cH(7, 7);
  114. Ranking ranks[7] {
  115. { std::vector<Candidate<int> >{ cH } },
  116. { std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH } },
  117. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cC, cE } },
  118. { std::vector<Candidate<int> >{ cA, cB, cC, cD, cE, cF, cG, cH } },
  119. { std::vector<Candidate<int> >{ cC, cD, cE, cF, cG, cH }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cB } },
  120. { std::vector<Candidate<int> >{ cD, cF }, std::vector<Candidate<int> >{ cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cC, cE, cH } },
  121. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cB, cC }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cE } }
  122. };
  123. std::vector<Candidate<int>> clist { cA, cB, cC, cD, cE, cF, cG, cH };
  124. std::list<Ranking> rlist(std::begin(ranks), std::end(ranks));
  125. Schulze s;
  126. VoteResult expResult { cD, cG, cF, cB, cA, cC, cE, cH };
  127. VoteResult result = s.calc(rlist, clist);
  128. BOOST_CHECK_EQUAL(expResult, result);
  129. auto i = clist.begin();
  130. BOOST_CHECK_EQUAL(6, i->getVictories());
  131. BOOST_CHECK_EQUAL(3, i->getIndex());
  132. i++;
  133. BOOST_CHECK_EQUAL(6, i->getVictories());
  134. BOOST_CHECK_EQUAL(6, i->getIndex());
  135. i++;
  136. BOOST_CHECK_EQUAL(5, i->getVictories());
  137. BOOST_CHECK_EQUAL(5, i->getIndex());
  138. i++;
  139. BOOST_CHECK_EQUAL(4, i->getVictories());
  140. BOOST_CHECK_EQUAL(1, i->getIndex());
  141. i++;
  142. BOOST_CHECK_EQUAL(3, i->getVictories());
  143. BOOST_CHECK_EQUAL(0, i->getIndex());
  144. i++;
  145. BOOST_CHECK_EQUAL(1, i->getVictories());
  146. BOOST_CHECK_EQUAL(2, i->getIndex());
  147. i++;
  148. BOOST_CHECK_EQUAL(1, i->getVictories());
  149. BOOST_CHECK_EQUAL(4, i->getIndex());
  150. i++;
  151. BOOST_CHECK_EQUAL(0, i->getVictories());
  152. BOOST_CHECK_EQUAL(7, i->getIndex());
  153. }
  154. BOOST_AUTO_TEST_CASE(CheckSchulzeWorkshopExample2) {
  155. Candidate<int> cA(0, 0), cB(1, 1), cC(2, 2), cD(3, 3), cE(4, 4), cF(5, 5), cG(6, 6), cH(7, 7);
  156. Ranking ranks[] {
  157. { std::vector<Candidate<int> >{ cH } },
  158. { std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH } },
  159. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cC, cE } },
  160. { std::vector<Candidate<int> >{ cA, cB, cC, cD, cE, cF, cG, cH } },
  161. { std::vector<Candidate<int> >{ cC, cD, cE, cF, cG, cH }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cB } },
  162. { std::vector<Candidate<int> >{ cD, cF }, std::vector<Candidate<int> >{ cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cC, cE, cH } },
  163. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cB, cC }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cE } },
  164. { std::vector<Candidate<int> >{ cH } },
  165. { std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH } },
  166. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cC, cE } },
  167. { std::vector<Candidate<int> >{ cA, cB, cC, cD, cE, cF, cG, cH } },
  168. { std::vector<Candidate<int> >{ cC, cD, cE, cF, cG, cH }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cB } },
  169. { std::vector<Candidate<int> >{ cD, cF }, std::vector<Candidate<int> >{ cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cC, cE, cH } },
  170. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cB, cC }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cE } }
  171. };
  172. std::vector<Candidate<int>> clist { cA, cB, cC, cD, cE, cF, cG, cH };
  173. std::list<Ranking> rlist(std::begin(ranks), std::end(ranks));
  174. Schulze s;
  175. VoteResult expResult { cD, cG, cF, cB, cA, cC, cE, cH };
  176. VoteResult result = s.calc(rlist, clist);
  177. BOOST_CHECK_EQUAL(expResult, result);
  178. auto i = clist.begin();
  179. BOOST_CHECK_EQUAL(6, i->getVictories());
  180. BOOST_CHECK_EQUAL(3, i->getIndex());
  181. i++;
  182. BOOST_CHECK_EQUAL(6, i->getVictories());
  183. BOOST_CHECK_EQUAL(6, i->getIndex());
  184. i++;
  185. BOOST_CHECK_EQUAL(5, i->getVictories());
  186. BOOST_CHECK_EQUAL(5, i->getIndex());
  187. i++;
  188. BOOST_CHECK_EQUAL(4, i->getVictories());
  189. BOOST_CHECK_EQUAL(1, i->getIndex());
  190. i++;
  191. BOOST_CHECK_EQUAL(3, i->getVictories());
  192. BOOST_CHECK_EQUAL(0, i->getIndex());
  193. i++;
  194. BOOST_CHECK_EQUAL(1, i->getVictories());
  195. BOOST_CHECK_EQUAL(2, i->getIndex());
  196. i++;
  197. BOOST_CHECK_EQUAL(1, i->getVictories());
  198. BOOST_CHECK_EQUAL(4, i->getIndex());
  199. i++;
  200. BOOST_CHECK_EQUAL(0, i->getVictories());
  201. BOOST_CHECK_EQUAL(7, i->getIndex());
  202. }
  203. struct SchulzeExposer : Schulze {
  204. using Schulze::calcDefeats;
  205. using Schulze::determineWinner;
  206. using Schulze::randomizeEqualPositions;
  207. };
  208. BOOST_AUTO_TEST_CASE(CheckRandomize) {
  209. std::vector<Candidate<int>> v { Candidate<int>(0, 0), Candidate<int>(1, 1), Candidate<int>(2, 2), Candidate<int>(3, 3) };
  210. v[0].setVictories(1);
  211. v[1].setVictories(2);
  212. v[2].setVictories(2);
  213. v[3].setVictories(4);
  214. Schulze s;
  215. (s.*&SchulzeExposer::randomizeEqualPositions)(v);
  216. BOOST_CHECK(v[0].getIndex() == 0);
  217. BOOST_CHECK(v[1].getIndex() == 1 || v[1].getIndex() == 2);
  218. BOOST_CHECK(v[2].getIndex() == 1 || v[2].getIndex() == 2);
  219. BOOST_CHECK(v[3].getIndex() == 3);
  220. }
  221. BOOST_AUTO_TEST_CASE(CheckRandomizeTwoPlateaus) {
  222. std::vector<Candidate<int>> v { Candidate<int>(0, 0), Candidate<int>(1, 1), Candidate<int>(2, 2), Candidate<int>(3, 3), Candidate<int>(4, 4), Candidate<int>(5, 5), Candidate<int>(6, 6), Candidate<int>(7, 7) };
  223. v[0].setVictories(1);
  224. v[1].setVictories(2);
  225. v[2].setVictories(2);
  226. v[3].setVictories(4);
  227. v[4].setVictories(4);
  228. v[5].setVictories(4);
  229. v[6].setVictories(5);
  230. v[7].setVictories(6);
  231. Schulze s;
  232. (s.*&SchulzeExposer::randomizeEqualPositions)(v);
  233. BOOST_CHECK(v[0].getIndex() == 0);
  234. BOOST_CHECK(v[1].getIndex() == 1 || v[1].getIndex() == 2);
  235. BOOST_CHECK(v[2].getIndex() == 1 || v[2].getIndex() == 2);
  236. BOOST_CHECK(v[3].getIndex() == 3 || v[3].getIndex() == 4 || v[3].getIndex() == 5);
  237. BOOST_CHECK(v[4].getIndex() == 3 || v[4].getIndex() == 4 || v[4].getIndex() == 5);
  238. BOOST_CHECK(v[5].getIndex() == 3 || v[5].getIndex() == 4 || v[5].getIndex() == 5);
  239. BOOST_CHECK(v[6].getIndex() == 6);
  240. BOOST_CHECK(v[7].getIndex() == 7);
  241. }
  242. BOOST_AUTO_TEST_CASE(CheckCalcDefeats) {
  243. Candidate<int> c1(0, 0), c2(1, 1);
  244. Ranking rank1, rank2 {c1, c2};
  245. rank1.setRank(c1, 1);
  246. rank1.setRank(c2, 1);
  247. std::vector<Candidate<int>> clist { c1, c2 };
  248. std::list<Ranking> rlist = { rank1, rank2 };
  249. Schulze s;
  250. Graph result = (s.*&SchulzeExposer::calcDefeats)(rlist, clist);
  251. BOOST_CHECK_EQUAL(2, boost::num_vertices(result));
  252. BOOST_CHECK_EQUAL(4, boost::num_edges(result));
  253. Edge e1, e2;
  254. bool ee1, ee2;
  255. boost::tie(e1, ee1) = boost::edge(c1.getIndex(), c2.getIndex(), result);
  256. boost::tie(e2, ee2) = boost::edge(c2.getIndex(), c1.getIndex(), result);
  257. BOOST_CHECK(ee1 && ee2);
  258. BOOST_CHECK_EQUAL(1, result[e1].defeats);
  259. BOOST_CHECK_EQUAL(0, result[e2].defeats);
  260. }
  261. BOOST_AUTO_TEST_CASE(CheckCalcDefeatsWikipediaExample) {
  262. Candidate<int> cA(0, 0), cB(1, 1), cC(2, 2), cD(3, 3), cE(4, 4);
  263. Ranking ranks[45];
  264. rankWikipedia(ranks, cA, cB, cC, cD, cE);
  265. std::vector<Candidate<int>> clist { cA, cB, cC, cD, cE };
  266. std::list<Ranking> rlist(std::begin(ranks), std::end(ranks));
  267. Schulze s;
  268. Graph result = (s.*&SchulzeExposer::calcDefeats)(rlist, clist);
  269. BOOST_CHECK_EQUAL(5, boost::num_vertices(result));
  270. BOOST_CHECK_EQUAL(25, boost::num_edges(result));
  271. Edge e;
  272. bool ee;
  273. int expResult[] = { 0, 20, 26, 30 ,22,
  274. 25, 0, 16, 33, 18,
  275. 19, 29, 0, 17, 24,
  276. 15, 12, 28, 0, 14,
  277. 23, 27, 21, 31, 0 };
  278. for(int i = 0; i < 25; ++i) {
  279. if(i % 5 != i / 5) {
  280. boost::tie(e, ee) = boost::edge(i / 5, i % 5, result);
  281. BOOST_CHECK(ee);
  282. BOOST_CHECK_EQUAL(expResult[i], result[e].defeats);
  283. }
  284. }
  285. }
  286. BOOST_AUTO_TEST_CASE(CheckCalcDefeatsWorkshopExample) {
  287. Candidate<int> cA(0, 0), cB(1, 1), cC(2, 2), cD(3, 3), cE(4, 4), cF(5, 5), cG(6, 6), cH(7, 7);
  288. Ranking ranks[7] {
  289. { std::vector<Candidate<int> >{ cH } },
  290. { std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH } },
  291. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cC, cE } },
  292. { std::vector<Candidate<int> >{ cA, cB, cC, cD, cE, cF, cG, cH } },
  293. { std::vector<Candidate<int> >{ cC, cD, cE, cF, cG, cH }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cB } },
  294. { std::vector<Candidate<int> >{ cD, cF }, std::vector<Candidate<int> >{ cG }, std::vector<Candidate<int> >{ cB }, std::vector<Candidate<int> >{ cA }, std::vector<Candidate<int> >{ cC, cE, cH } },
  295. { std::vector<Candidate<int> >{ cD, cG }, std::vector<Candidate<int> >{ cA, cF }, std::vector<Candidate<int> >{ cB, cC }, std::vector<Candidate<int> >{ cH }, std::vector<Candidate<int> >{ cE } }
  296. };
  297. ranks[0].setRank(cH, 1);
  298. ranks[1].setRank(cA, 1);
  299. ranks[1].setRank(cH, 2);
  300. ranks[2].setRank(cA, 7);
  301. ranks[2].setRank(cB, 2);
  302. ranks[2].setRank(cC, 8);
  303. ranks[2].setRank(cD, 1);
  304. ranks[2].setRank(cE, 8);
  305. ranks[2].setRank(cF, 7);
  306. ranks[2].setRank(cG, 1);
  307. ranks[3].setRank(cA, 1);
  308. ranks[3].setRank(cB, 1);
  309. ranks[3].setRank(cC, 1);
  310. ranks[3].setRank(cD, 1);
  311. ranks[3].setRank(cE, 1);
  312. ranks[3].setRank(cF, 1);
  313. ranks[3].setRank(cG, 1);
  314. ranks[3].setRank(cH, 1);
  315. ranks[4].setRank(cA, 2);
  316. ranks[4].setRank(cB, 4);
  317. ranks[4].setRank(cC, 1);
  318. ranks[4].setRank(cD, 1);
  319. ranks[4].setRank(cE, 1);
  320. ranks[4].setRank(cF, 1);
  321. ranks[4].setRank(cG, 1);
  322. ranks[4].setRank(cH, 3);
  323. ranks[5].setRank(cA, 7);
  324. ranks[5].setRank(cB, 3);
  325. ranks[5].setRank(cC, 8);
  326. ranks[5].setRank(cD, 1);
  327. ranks[5].setRank(cE, 8);
  328. ranks[5].setRank(cF, 1);
  329. ranks[5].setRank(cG, 2);
  330. ranks[5].setRank(cH, 8);
  331. ranks[6].setRank(cA, 2);
  332. ranks[6].setRank(cB, 4);
  333. ranks[6].setRank(cC, 4);
  334. ranks[6].setRank(cD, 1);
  335. ranks[6].setRank(cE, 8);
  336. ranks[6].setRank(cF, 2);
  337. ranks[6].setRank(cG, 1);
  338. ranks[6].setRank(cH, 5);
  339. std::vector<Candidate<int>> clist { cA, cB, cC, cD, cE, cF, cG, cH };
  340. std::list<Ranking> rlist(std::begin(ranks), std::end(ranks));
  341. Schulze s;
  342. Graph result = (s.*&SchulzeExposer::calcDefeats)(rlist, clist);
  343. BOOST_CHECK_EQUAL(8, boost::num_vertices(result));
  344. BOOST_CHECK_EQUAL(64, boost::num_edges(result));
  345. }
  346. BOOST_AUTO_TEST_CASE(CheckDetermineWinnerWikipediaExample) {
  347. Graph g;
  348. boost::add_vertex(0, g); // A
  349. boost::add_vertex(1, g); // B
  350. boost::add_vertex(2, g); // C
  351. boost::add_vertex(3, g); // D
  352. boost::add_vertex(4, g); // E
  353. CandidateRelation rel[20];
  354. rel[0].strongestPath = 28; // A -> B A A 3 win
  355. rel[1].strongestPath = 28; // A -> C A B 1 wins
  356. rel[2].strongestPath = 30; // A -> D A C 2 win
  357. rel[3].strongestPath = 24; // A -> E E D 0 wins
  358. rel[4].strongestPath = 25; // B -> A E 4 win
  359. rel[5].strongestPath = 28; // B -> C C
  360. rel[6].strongestPath = 33; // B -> D B
  361. rel[7].strongestPath = 24; // B -> E E
  362. rel[8].strongestPath = 25; // C -> A
  363. rel[9].strongestPath = 29; // C -> B
  364. rel[10].strongestPath = 29; // C -> D C
  365. rel[11].strongestPath = 24; // C -> E E
  366. rel[12].strongestPath = 25; // D -> A
  367. rel[13].strongestPath = 28; // D -> B
  368. rel[14].strongestPath = 28; // D -> C
  369. rel[15].strongestPath = 24; // D -> E E
  370. rel[16].strongestPath = 25; // E -> A
  371. rel[17].strongestPath = 28; // E -> B
  372. rel[18].strongestPath = 28; // E -> C
  373. rel[19].strongestPath = 31; // E -> D
  374. int c = 0;
  375. for(int i = 0; i < 5; i++) {
  376. for(int j = 0; j < 5; j++) {
  377. if(i != j) {
  378. boost::add_edge(i, j, rel[c], g);
  379. c++;
  380. }
  381. }
  382. }
  383. std::vector<Candidate<int>> l { Candidate<int>(0, 0), Candidate<int>(1, 1), Candidate<int>(2, 2), Candidate<int>(3, 3), Candidate<int>(4, 4) };
  384. Schulze s;
  385. (s.*&SchulzeExposer::determineWinner)(l, g);
  386. auto i = l.begin();
  387. BOOST_CHECK_EQUAL(4, i++->getIndex());
  388. BOOST_CHECK_EQUAL(0, i++->getIndex());
  389. BOOST_CHECK_EQUAL(2, i++->getIndex());
  390. BOOST_CHECK_EQUAL(1, i++->getIndex());
  391. BOOST_CHECK_EQUAL(3, i++->getIndex());
  392. }
  393. BOOST_AUTO_TEST_CASE(CheckDetermineWinnerTrivialExample) {
  394. Graph g;
  395. boost::add_vertex(0, g);
  396. boost::add_vertex(1, g);
  397. CandidateRelation rel[2];
  398. rel[0].strongestPath = 3;
  399. rel[1].strongestPath = 5;
  400. boost::add_edge(0, 1, rel[0], g);
  401. boost::add_edge(1, 0, rel[1], g);
  402. std::vector<Candidate<int>> l { Candidate<int>(0, 0), Candidate<int>(1, 1) };
  403. std::srand(0);
  404. Schulze s;
  405. (s.*&SchulzeExposer::determineWinner)(l, g);
  406. auto i = l.begin();
  407. BOOST_CHECK_EQUAL(1, i++->getIndex());
  408. BOOST_CHECK_EQUAL(0, i++->getIndex());
  409. }
  410. BOOST_AUTO_TEST_CASE(CheckDetermineWinnerTrivialExampleThree) {
  411. Graph g;
  412. boost::add_vertex(0, g);
  413. boost::add_vertex(1, g);
  414. boost::add_vertex(2, g);
  415. CandidateRelation rel[6];
  416. rel[0].strongestPath = 1;
  417. rel[1].strongestPath = 2;
  418. rel[2].strongestPath = 3;
  419. rel[3].strongestPath = 4;
  420. rel[4].strongestPath = 5;
  421. rel[5].strongestPath = 6;
  422. boost::add_edge(0, 1, rel[0], g);
  423. boost::add_edge(0, 2, rel[1], g);
  424. boost::add_edge(1, 0, rel[2], g);
  425. boost::add_edge(1, 2, rel[3], g);
  426. boost::add_edge(2, 0, rel[4], g);
  427. boost::add_edge(2, 1, rel[5], g);
  428. std::vector<Candidate<int>> l { Candidate<int>(0, 0), Candidate<int>(1, 1), Candidate<int>(2, 2) };
  429. std::srand(0);
  430. Schulze s;
  431. (s.*&SchulzeExposer::determineWinner)(l, g);
  432. auto i = l.begin();
  433. BOOST_CHECK_EQUAL(2, i++->getIndex());
  434. BOOST_CHECK_EQUAL(1, i++->getIndex());
  435. BOOST_CHECK_EQUAL(0, i++->getIndex());
  436. }