# 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) { |