+ IslandTradeEnd *src, *dst;
+} IslandTradeEndHeads;
+
+IslandTradeEndHeads *itradeends;
+ /* itradeends[islandid].{src,dst}->commodid etc. */
+
+static LPX *lp;
+static unsigned long generation;
+
+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_c(const Trade *t, IslandTradeEnd **trades,
+ int price, const char *srcdst,
+ int islandid, sqlite3_stmt *ss_ite) {
+ /* find row number of trade availability constraint */
+ IslandTradeEnd *search;
+
+ for (search= *trades; search; search=search->next)
+ if (search->commodid==t->commodid && search->price==price)
+ goto found;
+ abort();
+
+ found:;
+ if (search->generation != generation) {
+ search->rownum= lpx_add_rows(lp, 1);
+ lpx_set_row_bnds(lp, search->rownum, LPX_UP, 0, search->qty);
+
+ if (DEBUGP(value) || DEBUGP(check)) {
+ char *name= masprintf("%s_i%d_c%d_%d_all",
+ srcdst, islandid, t->commodid, price);
+ lpx_set_row_name(lp,search->rownum,name);
+
+ if (DEBUGP(check)) {
+ int nrows= lpx_get_num_rows(lp);
+ assert(search->rownum == nrows);
+ int i;
+ for (i=1; i<nrows; i++)
+ assert(strcmp(name, lpx_get_row_name(lp,i)));
+ }
+ free(name);
+ }
+ search->generation= generation;
+ }
+
+ add_constraint(search->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<legs; leg++) {
+ int row= leg+startrow;
+ lpx_set_row_bnds(lp, row, LPX_UP, 0, max_thing);
+ if (DEBUGP(value)) {
+ char *name= masprintf("%s_%d",wh,leg);
+ 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;
+ assert(value > 0);
+ add_constraint(startrow+leg, value);
+}
+
+IslandPair *ipair_get_maybe(int si, int di) {
+ IslandPair **ipa;
+
+ assert(si < islandtablesz);
+ assert(di < islandtablesz);