00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "base/commandlineflags.h"
00015 #include "base/logging.h"
00016 #include "graph/ebert_graph.h"
00017 #include "graph/max_flow.h"
00018 #include "graph/min_cost_flow.h"
00019
00020 namespace operations_research {
00021
00022
00023
00024
00025
00026 void MinCostFlowOn4x4Matrix() {
00027 LOG(INFO) << "Min Cost Flow on 4x4 Matrix";
00028 const int kNumSources = 4;
00029 const int kNumTargets = 4;
00030 const CostValue kCost[kNumSources][kNumTargets] = {
00031 { 90, 75, 75, 80 },
00032 { 35, 85, 55, 65 },
00033 { 125, 95, 90, 105 },
00034 { 45, 110, 95, 115 }
00035 };
00036 const CostValue kExpectedCost = 275;
00037 StarGraph graph(kNumSources + kNumTargets, kNumSources * kNumTargets);
00038 MinCostFlow min_cost_flow(&graph);
00039 for (NodeIndex source = 0; source < kNumSources; ++source) {
00040 for (NodeIndex target = 0; target < kNumTargets; ++target) {
00041 ArcIndex arc = graph.AddArc(source, kNumSources + target);
00042 min_cost_flow.SetArcUnitCost(arc, kCost[source][target]);
00043 min_cost_flow.SetArcCapacity(arc, 1);
00044 }
00045 }
00046 for (NodeIndex source = 0; source < kNumSources; ++source) {
00047 min_cost_flow.SetNodeSupply(source, 1);
00048 }
00049 for (NodeIndex target = 0; target < kNumTargets; ++target) {
00050 min_cost_flow.SetNodeSupply(kNumSources + target, -1);
00051 }
00052 CHECK(min_cost_flow.Solve());
00053 CHECK_EQ(MinCostFlow::OPTIMAL, min_cost_flow.status());
00054 CostValue total_flow_cost = min_cost_flow.GetOptimalCost();
00055 CHECK_EQ(kExpectedCost, total_flow_cost);
00056 }
00057
00058
00059
00060 void MaxFeasibleFlow() {
00061 LOG(INFO) << "Max Feasible Flow";
00062 const int kNumNodes = 6;
00063 const int kNumArcs = 9;
00064 const NodeIndex kTail[kNumArcs] = { 0, 0, 0, 0, 1, 2, 3, 3, 4 };
00065 const NodeIndex kHead[kNumArcs] = { 1, 2, 3, 4, 3, 4, 4, 5, 5 };
00066 const FlowQuantity kCapacity[kNumArcs] = { 5, 8, 5, 3, 4, 5, 6, 6, 4 };
00067 const FlowQuantity kExpectedFlow[kNumArcs] = { 4, 4, 2, 0, 4, 4, 0, 6, 4 };
00068 const FlowQuantity kExpectedTotalFlow = 10;
00069 StarGraph graph(kNumNodes, kNumArcs);
00070 MaxFlow max_flow(&graph, 0, kNumNodes - 1);
00071 for (int i = 0; i < kNumArcs; ++i) {
00072 ArcIndex arc = graph.AddArc(kTail[i], kHead[i]);
00073 max_flow.SetArcCapacity(arc, kCapacity[i]);
00074 }
00075 CHECK(max_flow.Solve());
00076 CHECK_EQ(MaxFlow::OPTIMAL, max_flow.status());
00077 FlowQuantity total_flow = max_flow.GetOptimalFlow();
00078 CHECK_EQ(total_flow, kExpectedTotalFlow);
00079 for (int i = 0; i < kNumArcs; ++i) {
00080 CHECK_EQ(kExpectedFlow[i], max_flow.Flow(i)) << " i = " << i;
00081 }
00082 }
00083 }
00084
00085 int main(int argc, char **argv) {
00086 google::ParseCommandLineFlags(&argc, &argv, true);
00087 operations_research::MinCostFlowOn4x4Matrix();
00088 operations_research::MaxFeasibleFlow();
00089 return 0;
00090 }
00091