|
1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library. |
|
4 * |
|
5 * Copyright (C) 2003-2010 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
9 * Permission to use, modify and distribute this software is granted |
|
10 * provided that this copyright notice appears in all copies. For |
|
11 * precise terms see the accompanying LICENSE file. |
|
12 * |
|
13 * This software is provided "AS IS" with no warranty of any kind, |
|
14 * express or implied, and with no claim as to its suitability for any |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 #include <sstream> |
|
20 #include <lemon/list_graph.h> |
|
21 #include <lemon/full_graph.h> |
|
22 #include <lemon/grid_graph.h> |
|
23 #include <lemon/lgf_reader.h> |
|
24 #include <lemon/grosso_locatelli_pullan_mc.h> |
|
25 |
|
26 #include "test_tools.h" |
|
27 |
|
28 using namespace lemon; |
|
29 |
|
30 char test_lgf[] = |
|
31 "@nodes\n" |
|
32 "label max_clique\n" |
|
33 "1 0\n" |
|
34 "2 0\n" |
|
35 "3 0\n" |
|
36 "4 1\n" |
|
37 "5 1\n" |
|
38 "6 1\n" |
|
39 "7 1\n" |
|
40 "@edges\n" |
|
41 " label\n" |
|
42 "1 2 1\n" |
|
43 "1 3 2\n" |
|
44 "1 4 3\n" |
|
45 "1 6 4\n" |
|
46 "2 3 5\n" |
|
47 "2 5 6\n" |
|
48 "2 7 7\n" |
|
49 "3 4 8\n" |
|
50 "3 5 9\n" |
|
51 "4 5 10\n" |
|
52 "4 6 11\n" |
|
53 "4 7 12\n" |
|
54 "5 6 13\n" |
|
55 "5 7 14\n" |
|
56 "6 7 15\n"; |
|
57 |
|
58 |
|
59 // Check with general graphs |
|
60 template <typename Param> |
|
61 void checkMaxCliqueGeneral(int max_sel, Param rule) { |
|
62 typedef ListGraph GR; |
|
63 typedef GrossoLocatelliPullanMc<GR> McAlg; |
|
64 typedef McAlg::CliqueNodeIt CliqueIt; |
|
65 |
|
66 // Basic tests |
|
67 { |
|
68 GR g; |
|
69 GR::NodeMap<bool> map(g); |
|
70 McAlg mc(g); |
|
71 check(mc.run(max_sel, rule) == 0, "Wrong clique size"); |
|
72 check(mc.cliqueSize() == 0, "Wrong clique size"); |
|
73 check(CliqueIt(mc) == INVALID, "Wrong CliqueNodeIt"); |
|
74 |
|
75 GR::Node u = g.addNode(); |
|
76 check(mc.run(max_sel, rule) == 1, "Wrong clique size"); |
|
77 check(mc.cliqueSize() == 1, "Wrong clique size"); |
|
78 mc.cliqueMap(map); |
|
79 check(map[u], "Wrong clique map"); |
|
80 CliqueIt it1(mc); |
|
81 check(static_cast<GR::Node>(it1) == u && ++it1 == INVALID, |
|
82 "Wrong CliqueNodeIt"); |
|
83 |
|
84 GR::Node v = g.addNode(); |
|
85 check(mc.run(max_sel, rule) == 1, "Wrong clique size"); |
|
86 check(mc.cliqueSize() == 1, "Wrong clique size"); |
|
87 mc.cliqueMap(map); |
|
88 check((map[u] && !map[v]) || (map[v] && !map[u]), "Wrong clique map"); |
|
89 CliqueIt it2(mc); |
|
90 check(it2 != INVALID && ++it2 == INVALID, "Wrong CliqueNodeIt"); |
|
91 |
|
92 g.addEdge(u, v); |
|
93 check(mc.run(max_sel, rule) == 2, "Wrong clique size"); |
|
94 check(mc.cliqueSize() == 2, "Wrong clique size"); |
|
95 mc.cliqueMap(map); |
|
96 check(map[u] && map[v], "Wrong clique map"); |
|
97 CliqueIt it3(mc); |
|
98 check(it3 != INVALID && ++it3 != INVALID && ++it3 == INVALID, |
|
99 "Wrong CliqueNodeIt"); |
|
100 } |
|
101 |
|
102 // Test graph |
|
103 { |
|
104 GR g; |
|
105 GR::NodeMap<bool> max_clique(g); |
|
106 GR::NodeMap<bool> map(g); |
|
107 std::istringstream input(test_lgf); |
|
108 graphReader(g, input) |
|
109 .nodeMap("max_clique", max_clique) |
|
110 .run(); |
|
111 |
|
112 McAlg mc(g); |
|
113 check(mc.run(max_sel, rule) == 4, "Wrong clique size"); |
|
114 check(mc.cliqueSize() == 4, "Wrong clique size"); |
|
115 mc.cliqueMap(map); |
|
116 for (GR::NodeIt n(g); n != INVALID; ++n) { |
|
117 check(map[n] == max_clique[n], "Wrong clique map"); |
|
118 } |
|
119 int cnt = 0; |
|
120 for (CliqueIt n(mc); n != INVALID; ++n) { |
|
121 cnt++; |
|
122 check(map[n] && max_clique[n], "Wrong CliqueNodeIt"); |
|
123 } |
|
124 check(cnt == 4, "Wrong CliqueNodeIt"); |
|
125 } |
|
126 } |
|
127 |
|
128 // Check with full graphs |
|
129 template <typename Param> |
|
130 void checkMaxCliqueFullGraph(int max_sel, Param rule) { |
|
131 typedef FullGraph GR; |
|
132 typedef GrossoLocatelliPullanMc<FullGraph> McAlg; |
|
133 typedef McAlg::CliqueNodeIt CliqueIt; |
|
134 |
|
135 for (int size = 0; size <= 40; size = size * 3 + 1) { |
|
136 GR g(size); |
|
137 GR::NodeMap<bool> map(g); |
|
138 McAlg mc(g); |
|
139 check(mc.run(max_sel, rule) == size, "Wrong clique size"); |
|
140 check(mc.cliqueSize() == size, "Wrong clique size"); |
|
141 mc.cliqueMap(map); |
|
142 for (GR::NodeIt n(g); n != INVALID; ++n) { |
|
143 check(map[n], "Wrong clique map"); |
|
144 } |
|
145 int cnt = 0; |
|
146 for (CliqueIt n(mc); n != INVALID; ++n) cnt++; |
|
147 check(cnt == size, "Wrong CliqueNodeIt"); |
|
148 } |
|
149 } |
|
150 |
|
151 // Check with grid graphs |
|
152 template <typename Param> |
|
153 void checkMaxCliqueGridGraph(int max_sel, Param rule) { |
|
154 GridGraph g(5, 7); |
|
155 GridGraph::NodeMap<char> map(g); |
|
156 GrossoLocatelliPullanMc<GridGraph> mc(g); |
|
157 check(mc.run(max_sel, rule) == 2, "Wrong clique size"); |
|
158 check(mc.cliqueSize() == 2, "Wrong clique size"); |
|
159 } |
|
160 |
|
161 |
|
162 int main() { |
|
163 checkMaxCliqueGeneral(50, GrossoLocatelliPullanMc<ListGraph>::RANDOM); |
|
164 checkMaxCliqueGeneral(50, GrossoLocatelliPullanMc<ListGraph>::DEGREE_BASED); |
|
165 checkMaxCliqueGeneral(50, GrossoLocatelliPullanMc<ListGraph>::PENALTY_BASED); |
|
166 |
|
167 checkMaxCliqueFullGraph(50, GrossoLocatelliPullanMc<FullGraph>::RANDOM); |
|
168 checkMaxCliqueFullGraph(50, GrossoLocatelliPullanMc<FullGraph>::DEGREE_BASED); |
|
169 checkMaxCliqueFullGraph(50, GrossoLocatelliPullanMc<FullGraph>::PENALTY_BASED); |
|
170 |
|
171 checkMaxCliqueGridGraph(50, GrossoLocatelliPullanMc<GridGraph>::RANDOM); |
|
172 checkMaxCliqueGridGraph(50, GrossoLocatelliPullanMc<GridGraph>::DEGREE_BASED); |
|
173 checkMaxCliqueGridGraph(50, GrossoLocatelliPullanMc<GridGraph>::PENALTY_BASED); |
|
174 |
|
175 return 0; |
|
176 } |