diff options
author | Carlo Zancanaro <carlo@carlo-laptop> | 2012-11-09 12:17:46 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@carlo-laptop> | 2012-11-09 12:17:46 +1100 |
commit | b19bd8d8a41664328f33c9b459b2b0100f0b303f (patch) | |
tree | c4ef4e35fe92d357cb75bbb38dadcddd52e26dde /impl/main.cpp | |
parent | 1e907d883191571b5c374fd1c3b2f6c1fe11da83 (diff) |
Add an MCF operator to the separate solver
For the solver utility it'd be good to have MCF problems, so here they
are!
Format is:
MCF<supplies, arcs>(cost*)
Supplies is a [int,int,int,...], where each int represents a new node
Arcs is [int:int, int:int, int:int, ...] where each int:int pair
represents an edge from the first to the second (1 indexed from the
"supplies" array).
Costs is the argument to the function. There must be as many costs as
arcs, and they are set from left to right, in order.
Diffstat (limited to 'impl/main.cpp')
-rw-r--r-- | impl/main.cpp | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/impl/main.cpp b/impl/main.cpp index be9cc82..0daa72a 100644 --- a/impl/main.cpp +++ b/impl/main.cpp @@ -20,6 +20,59 @@ extern "C" { using namespace std; template<typename T> +vector<T> toSupplies(pANTLR3_BASE_TREE node) { + ANTLR3_UINT32 num = node->getChildCount(node); + T output; + vector<T> supplies; + pANTLR3_BASE_TREE childNode; + + for (int i = 0; i < num; ++i) { + childNode = (pANTLR3_BASE_TREE) node->getChild(node, i); + stringstream stream((char*)childNode->getText(childNode)->chars); + assert(stream >> output); + supplies.push_back(output); + } + + return supplies; +} + +pair<int,int> toArc(pANTLR3_BASE_TREE node) { + pair<int,int> result; + int output; + pANTLR3_BASE_TREE childNode; + + ANTLR3_UINT32 num = node->getChildCount(node); + assert(num == 2); + + { + childNode = (pANTLR3_BASE_TREE) node->getChild(node, 0); + stringstream stream((char*)childNode->getText(childNode)->chars); + assert(stream >> output); + result.first = output; + } + + { + childNode = (pANTLR3_BASE_TREE) node->getChild(node, 1); + stringstream stream((char*)childNode->getText(childNode)->chars); + assert(stream >> output); + result.second = output; + } + + return result; +} + +vector<pair<int,int> > toArcs(pANTLR3_BASE_TREE node) { + vector<pair<int,int> > arcs; + ANTLR3_UINT32 num = node->getChildCount(node); + pANTLR3_BASE_TREE childNode; + for (int i = 0; i < num; ++i) { + childNode = (pANTLR3_BASE_TREE) node->getChild(node, i); + arcs.push_back(toArc(childNode)); + } + return arcs; +} + +template<typename T> Expression<T>& treeToExpression(pANTLR3_BASE_TREE node, EquationSystem<T>& system) { ANTLR3_UINT32 num = node->getChildCount(node); string name = (char*) node->getText(node)->chars; @@ -39,7 +92,23 @@ Expression<T>& treeToExpression(pANTLR3_BASE_TREE node, EquationSystem<T>& syste } } - // anything that's not a constant/variable + if (name == "MCF") { + pANTLR3_BASE_TREE childNode; + + childNode = (pANTLR3_BASE_TREE) node->getChild(node, 0); + vector<T> supplies = toSupplies<T>(childNode); + childNode = (pANTLR3_BASE_TREE) node->getChild(node, 1); + vector<pair<int,int> > arcs = toArcs(childNode); + + vector<Expression<T>*> args; + for (unsigned int i = 2; i < num; ++i) { + childNode = (pANTLR3_BASE_TREE) node->getChild(node, i); + args.push_back(&treeToExpression(childNode, system)); + } + return system.expression(new MinCostFlow<T>(supplies, arcs), args); + } + + // anything that's not a constant/variable, or an MCF expr vector<Expression<T>*> args; pANTLR3_BASE_TREE childNode; for (unsigned int i = 0; i < num; ++i) { @@ -70,7 +139,7 @@ Expression<T>& treeToExpression(pANTLR3_BASE_TREE node, EquationSystem<T>& syste } else if (name == "GUARD" || name == "guard") { op = new Guard<T>(); } else { - std::cout << "throw exception" << *(char*)NULL; + assert(false); //throw "Parse error: Unknown operator"; } return system.expression(op, args); |