# HG changeset patch
# User Daniel Poroszkai <poroszd@inf.elte.hu>
# Date 1328797331 -3600
# Node ID df198f12f7fa6af449bfb56cc9dd6e2bfacd88f7
# Parent ea93dc1490922914aac7dbfaeb71e9cffa7eaf6d
min cost flow algs included in benchmark
diff --git a/tools/bp-matching-benchmark.cc b/tools/bp-matching-benchmark.cc
a
|
b
|
|
24 | 24 | #include <lemon/matching.h> |
25 | 25 | #include <lemon/preflow.h> |
26 | 26 | #include <lemon/bp_matching.h> |
| 27 | #include <lemon/cost_scaling.h> |
| 28 | #include <lemon/capacity_scaling.h> |
| 29 | #include <lemon/network_simplex.h> |
27 | 30 | #include <iostream> |
28 | 31 | |
29 | 32 | using namespace std; |
… |
… |
|
55 | 58 | } |
56 | 59 | } |
57 | 60 | |
| 61 | template <typename BpGraph, typename BpCostMap, |
| 62 | typename Digraph, typename DgCostMap, typename SupplyMap> |
| 63 | void create_weighted_net(const BpGraph &bpg, |
| 64 | const BpCostMap &bpcost, |
| 65 | Digraph &dg, |
| 66 | DgCostMap &dgcost, |
| 67 | SupplyMap &supply) |
| 68 | { |
| 69 | dg.clear(); |
| 70 | typename Digraph::Node source = dg.addNode(); |
| 71 | supply.set(source, countBlueNodes(bpg) - countRedNodes(bpg)); |
| 72 | |
| 73 | typename BpGraph::template NodeMap<typename Digraph::Node> xref(bpg); |
| 74 | |
| 75 | for (typename BpGraph::RedNodeIt r(bpg); r!=INVALID; ++r) { |
| 76 | xref.set(r, dg.addNode()); |
| 77 | dgcost.set(dg.addArc(xref[r], source), 0); |
| 78 | supply.set(xref[r], 1); |
| 79 | } |
| 80 | for (typename BpGraph::BlueNodeIt b(bpg); b!=INVALID; ++b) { |
| 81 | xref.set(b, dg.addNode()); |
| 82 | dgcost.set(dg.addArc(source, xref[b]), 0); |
| 83 | supply.set(xref[b], -1); |
| 84 | } |
| 85 | |
| 86 | for (typename BpGraph::EdgeIt e(bpg); e!=INVALID; ++e) { |
| 87 | typename Digraph::Arc a = |
| 88 | dg.addArc(xref[bpg.redNode(e)], xref[bpg.blueNode(e)]); |
| 89 | dgcost.set(a, -bpcost[e]); |
| 90 | } |
| 91 | } |
| 92 | |
58 | 93 | typedef SmartDigraph Digraph; |
59 | 94 | typedef SmartBpGraph BpGraph; |
60 | 95 | |
… |
… |
|
76 | 111 | /// and the \ref lemon::Preflow "Preflow" algorithms for finding |
77 | 112 | /// a maximum cardinality bipartite matching, or the |
78 | 113 | /// \ref lemon::MaxWeightedBpMatching "max. weighted matching |
79 | | /// for sparse bipartite graphs" and the \ref lemon::MaxWeightedMatching |
80 | | /// "max. weighted matching for general graph" to find the maximum |
81 | | /// weighted matching. |
| 114 | /// for sparse bipartite graphs", the \ref lemon::MaxWeightedMatching |
| 115 | /// "max. weighted matching for general graph", \ref |
| 116 | /// lemon::CostScaling "cost scaling", \ref lemon::CapacityScaling |
| 117 | /// "capacity scaling" and \ref lemon::NetworkSimplex "network |
| 118 | /// simplex" algorithms to find the maximum weighted matching. |
82 | 119 | int main() { |
83 | 120 | DimacsDescriptor desc = dimacsType(cin); |
| 121 | int red_n, blue_n, edge_n = desc.edgeNum; |
84 | 122 | if (desc.type == DimacsDescriptor::UBM) { |
85 | 123 | // unweighted bipartite matching |
86 | 124 | Timer hk_t(false), mm_t(false), pf_t(false); |
| 125 | int hk_r, mm_r, pf_r; |
87 | 126 | |
88 | | BpGraph bpg; |
89 | | readDimacsUbm(cin, bpg, desc); |
| 127 | BpGraph *bpg = new BpGraph(); |
| 128 | readDimacsUbm(cin, *bpg, desc); |
| 129 | red_n = countRedNodes(*bpg); |
| 130 | blue_n = countBlueNodes(*bpg); |
90 | 131 | |
91 | | Digraph network; |
| 132 | { |
| 133 | hk_t.start(); |
| 134 | HopcroftKarp<BpGraph> hk(*bpg); |
| 135 | hk.run(); |
| 136 | hk_r = hk.matchingSize(); |
| 137 | hk_t.stop(); |
| 138 | } |
| 139 | { |
| 140 | mm_t.start(); |
| 141 | MaxMatching<BpGraph> mm(*bpg); |
| 142 | mm.run(); |
| 143 | mm_r = mm.matchingSize(); |
| 144 | mm_t.stop(); |
| 145 | } |
| 146 | |
| 147 | Digraph *network = new Digraph(); |
92 | 148 | Digraph::Node source, target; |
93 | | create_network(bpg, network, source, target); |
94 | | |
95 | | hk_t.start(); |
96 | | HopcroftKarp<BpGraph> hk(bpg); |
97 | | hk.run(); |
98 | | hk_t.stop(); |
99 | | |
100 | | mm_t.start(); |
101 | | MaxMatching<BpGraph> mm(bpg); |
102 | | mm.run(); |
103 | | mm_t.stop(); |
104 | | |
105 | | pf_t.start(); |
106 | | Preflow<Digraph, ConstMap<Digraph::Arc, int> > |
107 | | pf(network, constMap<Digraph::Arc, int>(1), source, target); |
108 | | pf.run(); |
109 | | pf_t.stop(); |
| 149 | create_network(*bpg, *network, source, target); |
| 150 | delete bpg; |
| 151 | { |
| 152 | pf_t.start(); |
| 153 | Preflow<Digraph, ConstMap<Digraph::Arc, long> > |
| 154 | pf(*network, constMap<Digraph::Arc, long>(1), source, target); |
| 155 | pf.run(); |
| 156 | pf_r = pf.flowValue(); |
| 157 | pf_t.stop(); |
| 158 | } |
| 159 | delete network; |
110 | 160 | |
111 | 161 | cout << "Benchmarking in unweighted case, using a bipartite graph\n" |
112 | | << "with " << countRedNodes(bpg) << " red, " |
113 | | << countBlueNodes(bpg) << " blue nodes, and " |
114 | | << desc.edgeNum << " edges.\n" |
| 162 | << "with " << red_n << " red, " << blue_n << " blue nodes, and " |
| 163 | << edge_n << " edges.\n" |
115 | 164 | << "--------------------------------------------------------\n" |
116 | 165 | << "Algorithm used Matching size Time\n" |
117 | | << "Hopcroft-Karp " << hk.matchingSize() |
| 166 | << "Hopcroft-Karp " << hk_r |
118 | 167 | << " " << hk_t.realTime() << "\n" |
119 | | << "General matching " << mm.matchingSize() |
| 168 | << "General matching " << mm_r |
120 | 169 | << " " << mm_t.realTime() << "\n" |
121 | | << "Preflow " << pf.flowValue() |
| 170 | << "Preflow " << pf_r |
122 | 171 | << " " << pf_t.realTime() << endl; |
123 | 172 | |
124 | 173 | } else if (desc.type == DimacsDescriptor::WBM) { |
125 | 174 | // weighted bipartite matching |
126 | | Timer bm_t(false), gm_t(false); |
| 175 | Timer bm_t(false), |
| 176 | gm_t(false), |
| 177 | cas_t(false), |
| 178 | cos_t(false), |
| 179 | ns_t(false); |
| 180 | int bm_r, gm_r, cas_r, cos_r, ns_r; |
127 | 181 | |
128 | | BpGraph bpg; |
129 | | BpGraph::EdgeMap<int> weight(bpg); |
130 | | readDimacsWbm(cin, bpg, weight, desc); |
| 182 | BpGraph *bpg = new BpGraph(); |
| 183 | BpGraph::EdgeMap<long> *weight = new BpGraph::EdgeMap<long>(*bpg); |
| 184 | readDimacsWbm(cin, *bpg, *weight, desc); |
| 185 | red_n = countRedNodes(*bpg); |
| 186 | blue_n = countBlueNodes(*bpg); |
131 | 187 | |
132 | | bm_t.start(); |
133 | | MaxWeightedBpMatching<BpGraph> bm(bpg, weight); |
134 | | bm.run(); |
135 | | bm_t.stop(); |
| 188 | { |
| 189 | bm_t.start(); |
| 190 | MaxWeightedBpMatching<BpGraph, BpGraph::EdgeMap<long> > bm(*bpg, *weight); |
| 191 | bm.run(); |
| 192 | bm_r = bm.matchingWeight(); |
| 193 | bm_t.stop(); |
| 194 | } |
| 195 | { |
| 196 | gm_t.start(); |
| 197 | MaxWeightedMatching<BpGraph, BpGraph::EdgeMap<long> > gm(*bpg, *weight); |
| 198 | gm.run(); |
| 199 | gm_r = gm.matchingWeight(); |
| 200 | gm_t.stop(); |
| 201 | } |
136 | 202 | |
137 | | gm_t.start(); |
138 | | MaxWeightedMatching<BpGraph> gm(bpg, weight); |
139 | | gm.run(); |
140 | | gm_t.stop(); |
| 203 | Digraph *g = new Digraph(); |
| 204 | Digraph::ArcMap<long> *cost = new Digraph::ArcMap<long>(*g); |
| 205 | Digraph::NodeMap<long> *supply = new Digraph::NodeMap<long>(*g); |
| 206 | create_weighted_net(*bpg, *weight, *g, *cost, *supply); |
| 207 | delete bpg; |
| 208 | delete weight; |
| 209 | { |
| 210 | cas_t.start(); |
| 211 | CapacityScaling<Digraph> cas(*g); |
| 212 | cas.costMap(*cost) |
| 213 | .supplyMap(*supply) |
| 214 | .upperMap(constMap<Digraph::Arc, long>(1)); |
| 215 | cas.run(); |
| 216 | cas_r = cas.totalCost(); |
| 217 | cas_t.stop(); |
| 218 | } |
| 219 | { |
| 220 | cos_t.start(); |
| 221 | CostScaling<Digraph> cos(*g); |
| 222 | cos.costMap(*cost) |
| 223 | .supplyMap(*supply) |
| 224 | .upperMap(constMap<Digraph::Arc, long>(1)); |
| 225 | cos.run(); |
| 226 | cos_r = cos.totalCost(); |
| 227 | cos_t.stop(); |
| 228 | } |
| 229 | { |
| 230 | ns_t.start(); |
| 231 | NetworkSimplex<Digraph> ns(*g); |
| 232 | ns.costMap(*cost) |
| 233 | .supplyMap(*supply) |
| 234 | .upperMap(constMap<Digraph::Arc, long>(1)); |
| 235 | ns.run(); |
| 236 | ns_r = ns.totalCost(); |
| 237 | ns_t.stop(); |
| 238 | } |
| 239 | delete g; |
| 240 | delete cost; |
| 241 | delete supply; |
141 | 242 | |
142 | 243 | cout << "Benchmarking on weighted bipartite matching problem on a " |
143 | | << "graph\nwith " << countRedNodes(bpg) << " red, " |
144 | | << countBlueNodes(bpg) << " blue nodes and " |
145 | | << desc.edgeNum << " edges\n" |
| 244 | << "graph\nwith " << red_n << " red, " << blue_n |
| 245 | << " blue nodes and " << edge_n << " edges\n" |
146 | 246 | << "--------------------------------------------------------\n" |
147 | 247 | << "Algorithm used Maximum weight Time\n" |
148 | | << "Bipartite matching " << bm.matchingWeight() |
| 248 | << "Bipartite matching " << bm_r |
149 | 249 | << " " << bm_t.realTime() << "\n" |
150 | | << "General matching " << gm.matchingWeight() |
151 | | << " " << gm_t.realTime() << endl; |
| 250 | << "General matching " << gm_r |
| 251 | << " " << gm_t.realTime() << "\n" |
| 252 | << "Capacity scaling " << -cas_r |
| 253 | << " " << cas_t.realTime() << "\n" |
| 254 | << "Cost scaling " << -cos_r |
| 255 | << " " << cos_t.realTime() << "\n" |
| 256 | << "Network simplex " << -ns_r |
| 257 | << " " << ns_t.realTime() << endl; |
152 | 258 | |
153 | 259 | } else { |
154 | 260 | cerr << "Wrong problem type." << endl; |
diff --git a/tools/unweighted-bp-gen.cc b/tools/unweighted-bp-gen.cc
a
|
b
|
|
61 | 61 | rnd.seed(seed); |
62 | 62 | |
63 | 63 | |
64 | | long max_edge = red*blue; |
| 64 | long max_edge = static_cast<long>(red)*blue; |
65 | 65 | long edge_left = density; |
66 | 66 | |
67 | 67 | if (max_edge < density) { |
diff --git a/tools/weighted-bp-gen.cc b/tools/weighted-bp-gen.cc
a
|
b
|
|
71 | 71 | rnd.seed(seed); |
72 | 72 | |
73 | 73 | |
74 | | long max_edge = red*blue; |
| 74 | long max_edge = static_cast<long>(red)*blue; |
75 | 75 | long edge_left = density; |
76 | 76 | |
77 | 77 | if (max_edge < density) { |