Thanks to you both, those are some nice tricks/insights!

On Monday, February 15, 2016 at 9:01:41 PM UTC-5, Steven Dirkse wrote:

Iain,

Your question was an interesting one for a rainy night. A lot of this is just a matter of taste: I’ve taken the liberty of doing some minimal changes to come up with the “how-I-would-do-it” model (attached). Some of the changes are very minor: using the alternative curly braces for sums, grouping the declarations, indentation. Others are less minor. For a variable like flow, it’s better to declare it positive. That way, you don’t store the lower bounds of zero, since that is the default/declared lower bound. You can always set a non-zero lower bound, which will get stored. For the flow conservation constraint, I have

equation flowcon(nodes);

flowcon(midnodes(n))… sum{edges(nodefrom,n), flow(nodefrom,n)} =e= sum{edges(n,nodeto), flow(n,nodeto)};

Note there are no explicit -conditions, but the sums are exactly the same. Internally, they are identical. It's just clearer, IMHO, not to use the explicit -conditions in many cases, including this one. More subtle is the declaration (over the entire set) vs. the definition (over the subset midnodes with a sort of dummy index n). This is handy. The dummy index n lets you copy-paste commonly used expressions or code fragments, because it’s generic. You only mention midnodes once, to specify the nodes n you really want to generate this equation for. If your set midnodes was dynamic, you couldn’t declare the equation over the midnodes set, so the distinction between declaring over static sets and defining over potentially dynamic sets would be an important one.

It is not possible to declare and define an equation in the same statement. You can do it in the same line, but that’s probably not what you mean.

EQUATION flowcost; flowcost… z =e= sum(edges, cost(edges) * flow(edges));

I liked Claudio’s breakdown into sources and sinks. One neat/cute/potentially-powerful change would be to compute the source and sink sets based on the arc set. You could have multiple sources and multiple sinks. The flow conservation would then look something like this:

flowcon(n)$[not source(n)]… sum{edges(nodefrom,n), flow(nodefrom,n)} =e= sum{edges(n,nodeto), flow(n,nodeto)} + 1$sink(n);

and you could drop the unitflow equation. You could do something similar to your original model too, so that you only need to define source and sink sets, not the midnodes set. How you define the source & sink sets is independent of that. That is attached as steve2.

-Steve

On Thu, Feb 11, 2016 at 10:29 PM, Iain Dunning wrote:

Hello,

I’m trying to make the following GAMS model as terse (in particular, as few lines as possible) and as idiomatic as possible.

In words, the file defines a graph with five nodes, and six directed edges, each with its own capacity and cost.

The total flow into node 5 should equal one.

Nodes 2 through 4 should conserve flow - i.e. flow in = flow out.

Node 1 can produce as must flow as it likes, and as I said before, node 5 must consume exactly 1 unit of flow.

The objective function is to minimize the cost of sending this unit of flow from node 1 to node 5.

Here is my attempt, as an amateur:

SET nodes /n1*n5/;*

ALIAS(nodes,nodefrom,nodeto);

SET midnodes(nodes) /n2n4/;

SET lastnode(nodes) /n5/;

SET edges(nodes,nodes) / n1 . n2

n1 . n3

n1 . n4

n2 . n5

n3 . n5

n4 . n5 /;

PARAMETER cost(nodes,nodes) / n1.n2 1

n1.n3 2

n1.n4 3

n2.n5 2

n3.n5 2

n4.n5 2 /;

PARAMETER cap(nodes,nodes) / n1.n2 0.5

n1.n3 0.4

n1.n4 0.6

n2.n5 0.3

n3.n5 0.6

n4.n5 0.5 /;

VARIABLE flow(nodefrom,nodeto), z;

flow.LO(edges) = 0;

flow.UP(edges) = cap(edges);

EQUATION flowcost;

flowcost… z =e= sum(edges, cost(edges) * flow(edges));

EQUATION unitflow;

unitflow… 1 =e= sum((nodefrom,lastnode)$edges(nodefrom,lastnode), flow(nodefrom,lastnode));

EQUATION flowcon(midnodes);

flowcon(midnodes)… sum(nodefrom$edges(nodefrom,midnodes), flow(nodefrom,midnodes)) =e=

sum(nodeto$edges(midnodes,nodeto), flow(midnodes,nodeto));

MODEL mincostflow /all/;

SOLVE mincostflow USING lp MINIMIZING z;

I realize its probably not possible to make the PARAMETER section any shorter without harming readability, so I’m not so worried about that.

I’m more interested to know if:

- Can the flow conservation constraint be shortened somehow? “midnodes” is repeated 6 times in two lines.
- Can the EQUATION and its definition be defined on one line, e.g. for flowcost?
- Can I do without lastnode?

I’m sure to the expert eye, other opportunities for refinement could present themselves - I want to present GAMS in the best light possible.

Thanks,

Iain

Steven Dirkse, Ph.D.

GAMS Development Corp., Washington DC

Voice: (202)342-0180 Fax: (202)342-0181

sdi...@gams.com

http://www.gams.com

–

To unsubscribe from this group and stop receiving emails from it, send an email to gamsworld+unsubscribe@googlegroups.com.

To post to this group, send email to gamsworld@googlegroups.com.

Visit this group at https://groups.google.com/group/gamsworld.

For more options, visit https://groups.google.com/d/optout.