+typedef struct IslandTradeEnd {
+ struct IslandTradeEnd *next;
+ int commodid, price;
+ int qty, rownum;
+} IslandTradeEnd, *IslandDirnTradeEnds;
+
+typedef struct {
+ int islandid;
+ IslandDirnTradeEnds collect, deliver;
+} IslandTradeEnds;
+
+static struct obstack ites_obstack;
+static LPX *lp;
+
+static int nconstraint_rows;
+static int constraint_rows[1+2+3*MAX_LEGS];
+static double constraint_coeffs[1+2+3*MAX_LEGS];
+ /* dummy0, src, dst, for_each_leg( [mass], [volume], [capital] ) */
+
+static void add_constraint(int row, double coefficient) {
+ nconstraint_rows++; /* glpk indices start from 1 !!! */
+ constraint_rows [nconstraint_rows]= row;
+ constraint_coeffs[nconstraint_rows]= coefficient;
+}
+
+static void avail_constraint(const Trade *t, IslandDirnTradeEnds *trades,
+ int price, int qty, const char *srcdst) {
+ /* find row number of trade availability constraint */
+ IslandTradeEnd *search;
+
+ for (search= *trades; search; search=search->next)
+ if (search->commodid==t->commodid && search->price==price) {
+ assert(search->qty == qty);
+ goto found;
+ }
+ /* not found, add new row */
+ search= obstack_alloc(&ites_obstack, sizeof(*search));
+ search->commodid= t->commodid;
+ search->price= price;
+ search->qty= qty;
+ search->rownum= lpx_add_rows(lp, 1);
+ search->next= *trades;
+ if (DEBUGP(value)) {
+ char *name= masprintf("%s_commod%d_price%d",srcdst,t->commodid,price);
+ lpx_set_row_name(lp,search->rownum,name);
+ free(name);
+ }
+ *trades= search;
+ found:;
+ int rownum= search->rownum;
+
+ lpx_set_row_bnds(lp, rownum, LPX_UP, 0, qty);
+ add_constraint(rownum, 1.0);
+}
+
+static int setup_leg_constraints(double max_thing, int legs, const char *wh) {
+ int leg, startrow;
+ if (max_thing < 0 || !legs) return -1;
+ startrow= lpx_add_rows(lp, legs);
+ for (leg=0; leg<nislands-1; leg++) {
+ int row= leg+startrow;
+ lpx_set_row_bnds(lp, row, LPX_UP, 0, max_thing);
+ if (DEBUGP(value)) {
+ char *name= masprintf("max_leg%d_%s",leg,wh);
+ lpx_set_row_name(lp,row,name);
+ free(name);
+ }
+ }
+ return startrow;
+}
+
+static void add_leg_c(int startrow, int leg, double value) {
+ if (startrow<=0) return;
+ add_constraint(startrow+leg, value);
+}
+