chiark / gitweb /
WIP routesearch; before try not using interior point
authorIan Jackson <ian@liberator.(none)>
Fri, 2 Oct 2009 21:58:26 +0000 (22:58 +0100)
committerIan Jackson <ian@liberator.(none)>
Fri, 2 Oct 2009 21:58:26 +0000 (22:58 +0100)
yarrg/Makefile
yarrg/common.h
yarrg/rscommon.h
yarrg/rsmain.c
yarrg/rssql.c [moved from yarrg/rssetup.c with 51% similarity]
yarrg/rsvalue.c

index ca05ff5..ed4f372 100644 (file)
@@ -38,7 +38,7 @@ all: default routesearch
 
 CONVERT_OBJS= convert.o ocr.o pages.o structure.o rgbimage.o resolve.o
 COMMON_OBJS= common.o
-ROUTESEARCH_OBJS= rsvalue.o rsmain.o rssetup.o
+ROUTESEARCH_OBJS= rsvalue.o rsmain.o rssql.o
 
 yarrg: $(CONVERT_OBJS) $(COMMON_OBJS) -lnetpbm -lXtst -lX11 -lpcre -lm
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
index 0856274..22f61cb 100644 (file)
@@ -86,7 +86,9 @@ enum {
 extern unsigned debug_flags;
 
 void debug_flush(void);
-#define debug stderr
+#ifndef debug
+# define debug stderr
+#endif
 
 #define FMT(f,a) __attribute__((format(printf,f,a)))
 #define SCANFMT(f,a) __attribute__((format(scanf,f,a)))
index b1003bf..860409e 100644 (file)
@@ -5,20 +5,26 @@
 
 #define DEBUG_FLAG_LIST                                \
    DF(sql)                                     \
-   DF(value)
+   DF(sql2)                                    \
+   DF(value)                                   \
+   DF(lp)
+#define debug stdout
+
+#include "common.h"
 
 
-#define SQL_MUST( call ) ({                                     \
+#define SQL_MUST( call ) ({                                             \
     /* `call' is an expression returning result, using  const char *sqe; \
      * chk1 and chk2 are blocks using sqe and  int sqr; */              \
     const char *sql_must_call_string= #call;                            \
     int sqr;                                                            \
-    if (DEBUGP(sql)) fprintf(stderr,"SQL %s", sql_must_call_string);    \
+    if (DEBUGP(sql2)) fprintf(stderr,"SQL %s", sql_must_call_string);   \
     sqr= (call);                                                        \
-    if (DEBUGP(sql)) fprintf(stderr," = %d\n", sqr);                    \
-    if (sqr) fatal("SQL call failed code %d: %s: %s",                   \
-                  sqr, sqlite3_errmsg(db), sql_must_call_string);       \
-  })
+    if (DEBUGP(sql2)) fprintf(stderr," = %d\n", sqr);                   \
+    if (sqr) sql_fatal("(unknown)", sqr, sql_must_call_string);                 \
+  })                                                                    \
+
+void sql_fatal(const char *stmt_what, int sqr, const char *act_what) NORET;
 
 #define SQL_STEP(ssh) (sql_step_wrap((ssh), #ssh, __FILE__, __LINE__))
 int sql_step_wrap(sqlite3_stmt *ssh, const char *ssh_string,
@@ -26,14 +32,19 @@ int sql_step_wrap(sqlite3_stmt *ssh, const char *ssh_string,
 
 int sql_single_int(const char *stmt);
 
-#define MAX_ROUTELEN 20
+#define SQL_PREPARE(ss,stmt) ((ss)= sql_prepare((stmt),#ss))
+sqlite3_stmt *sql_prepare(const char *stmt, const char *what);
 
-#include "common.h"
+#define SQL_BIND(ss,index,value) (sql_bind((ss),(index),(value),#ss,#value))
+void sql_bind(sqlite3_stmt *ss, int index, int value,
+             const char *ss_what, const char *val_what);
+
+#define MAX_ROUTELEN 20
 
 extern sqlite3 *db;
 
 void setup(void);
-void value_route(int nislands, const int *islands);
+double value_route(int nislands, const int *islands);
 void setup_value(void);
 void setup_commods(void);
 
index ed17635..49a59a4 100644 (file)
@@ -9,7 +9,7 @@ double distance_loss_factor_per_league;
 int main(int argc, const char **argv) {
   int ia[argc], ni=0;
 
-  debug_flags= ~0UL;
+  debug_flags= ~( dbg_sql2 );
   setup();
 
   max_mass= atof(*++argv);
@@ -24,6 +24,7 @@ int main(int argc, const char **argv) {
   while ((arg= *++argv)) {
     ia[ni++]= atoi(arg);
   }
-  value_route(ni, ia);
+  double val= value_route(ni, ia);
+  printf("route value is %g\n", val);
   return 0;
 }
similarity index 51%
rename from yarrg/rssetup.c
rename to yarrg/rssql.c
index dadeca6..463ef8b 100644 (file)
@@ -4,8 +4,10 @@
 sqlite3 *db;
 sqlite3_stmt *ss_ipair;
 
+DEBUG_DEFINE_DEBUGF(sql);
+
 static int busy_handler(void *u, int previous) {
-  if (DEBUGP(sql)) fprintf(stderr,"[[DB BUSY %d]]",previous);
+  debugf("[[DB BUSY %d]]",previous);
   sysassert(! usleep(5000) );
   return 1;
 }
@@ -16,7 +18,7 @@ void setup(void) {
   SQL_MUST( sqlite3_open("OCEAN-Midnight.db", &db) );
   SQL_MUST( sqlite3_busy_handler(db, busy_handler, 0) );
 
-  SQL_MUST( sqlite3_prepare(db, "BEGIN", -1, &sst, 0) );
+  sst= sql_prepare("BEGIN","(begin)");
   assert( !SQL_STEP(sst) );
   sqlite3_finalize(sst);
 
@@ -25,13 +27,33 @@ void setup(void) {
 
 int sql_single_int(const char *stmt) {
   sqlite3_stmt *sst;
-  SQL_MUST( sqlite3_prepare(db, stmt, -1,&sst,0) );
+  sst= sql_prepare(stmt,"(single int)");
   assert( SQL_STEP(sst) );
   int rv= sqlite3_column_int(sst,0);
   sqlite3_finalize(sst);
   return rv;
 }
 
+void sql_fatal(const char *stmt_what, int sqr, const char *act_what) {
+  fatal("SQL call failed, stmt %s code %d: %s: %s",
+       stmt_what, sqr, sqlite3_errmsg(db), act_what);
+}
+
+void sql_bind(sqlite3_stmt *ss, int index, int value,
+             const char *ss_what, const char *val_what) {
+  debugf("SQL BIND %s #%d = %d = %s\n", ss_what, index, value, val_what);
+  int sqr= sqlite3_bind_int(ss, index, value);
+  if (sqr) sql_fatal(ss_what, sqr,
+                    masprintf("bind #%d (%s)", index, val_what));
+}
+  
+sqlite3_stmt *sql_prepare(const char *stmt, const char *what) {
+  sqlite3_stmt *ssr;
+  debugf("SQL PREPARE %s [[\n%s\n]]\n", what, stmt);
+  SQL_MUST( sqlite3_prepare(db, stmt, -1, &ssr, 0) );
+  return ssr;
+}
+
 int sql_step_wrap(sqlite3_stmt *ssh, const char *ssh_string,
                  const char *file, int line) {
   for (;;) {
@@ -39,19 +61,18 @@ int sql_step_wrap(sqlite3_stmt *ssh, const char *ssh_string,
     sqr= sqlite3_step((ssh));
     switch (sqr) {
     case SQLITE_DONE:
-      if (DEBUGP(sql))
-       fprintf(stderr,"SQL %s DONE\n",ssh_string);
+      debugf("SQL %s DONE\n",ssh_string);
       return 0;
     case SQLITE_ROW:
       if (DEBUGP(sql)) {
        int i;
-       fprintf(stderr,"SQL %s R",ssh_string);
+       fprintf(debug,"SQL %s R",ssh_string);
        for (i=0; i<sqlite3_column_count(ssh); i++) {
-         fputc('\t',stderr);
+         fputc('\t',debug);
          const char *txt= (const char*)sqlite3_column_text(ssh,i);
-         fputs(txt ? txt : "<null>", stderr);
+         fputs(txt ? txt : "<null>", debug);
        }
-       fputs("\n",stderr);
+       fputs("\n",debug);
       }
       return 1;
     default: fatal("SQL step failed at %s:%d: code %d: %s: %s",
index a1cdf0f..135583e 100644 (file)
@@ -16,7 +16,7 @@ static sqlite3_stmt *ss_ite_buy, *ss_ite_sell;
 #define MAX_LEGS (MAX_ROUTELEN-1)
 
 typedef struct {
-  int commodid, src_price, src_qty, dst_price, dst_qty;
+  int commodid, src_price, dst_price;
 } Trade;
 
 #define TRADES_PER_BLOCK 10
@@ -79,9 +79,9 @@ static void avail_c(const Trade *t, IslandDirnTradeEnds *trades,
   search->next= *trades;
   search->generation= 0;
 
-  SQL_MUST( sqlite3_bind_int(ss_ite, 1, islandid) );
-  SQL_MUST( sqlite3_bind_int(ss_ite, 2, t->commodid) );
-  SQL_MUST( sqlite3_bind_int(ss_ite, 3, price) );
+  SQL_BIND(ss_ite, 1, islandid);
+  SQL_BIND(ss_ite, 2, t->commodid);
+  SQL_BIND(ss_ite, 3, price);
   assert(SQL_STEP(ss_ite));
   search->qty= sqlite3_column_int(ss_ite, 0);
   SQL_MUST( sqlite3_reset(ss_ite) );
@@ -94,7 +94,7 @@ static void avail_c(const Trade *t, IslandDirnTradeEnds *trades,
     lpx_set_row_bnds(lp, search->rownum, LPX_UP, 0, search->qty);
 
     if (DEBUGP(value)) {
-      char *name= masprintf("%s_commod%d_price%d",srcdst,t->commodid,price);
+      char *name= masprintf("%s_c%d_%d",srcdst,t->commodid,price);
       lpx_set_row_name(lp,search->rownum,name);
       free(name);
     }
@@ -163,7 +163,7 @@ static IslandPair *ipair_get(int si, int di) {
       inblock= 0;
     }
     int *irp, i;
-    for (i=0, irp=&block->t[inblock].commodid; i<5; i++, irp++)
+    for (i=0, irp=&block->t[inblock].commodid; i<3; i++, irp++)
       *irp= sqlite3_column_int(ss_ipair_trades, i);
     ip->ntrades++;
     inblock++;
@@ -176,7 +176,7 @@ static IslandPair *ipair_get(int si, int di) {
   return ip;
 }
 
-void value_route(int nislands, const int *islands) {
+double value_route(int nislands, const int *islands) {
   int s,d;
 
   /* We need to construct the LP problem.  GLPK talks
@@ -234,6 +234,8 @@ void value_route(int nislands, const int *islands) {
   assert(!lp);
   lp= lpx_create_prob();
   lpx_set_obj_dir(lp, LPX_MAX);
+  lpx_set_int_parm(lp, LPX_K_MSGLEV, DEBUGP(lp) ? 3 : 1);
+
   if (DEBUGP(value)) {
     lpx_set_prob_name(lp,(char*)"value_route");
     lpx_set_obj_name(lp,(char*)"profit");
@@ -303,11 +305,13 @@ void value_route(int nislands, const int *islands) {
        lpx_set_mat_col(lp, col, nconstraint_rows,
                        constraint_rows, constraint_coeffs);
        if (DEBUGP(value)) {
-         char *name= masprintf("trade_commod%d_port%d_at%d_port%d_at%d",
+         char *name= masprintf("c%d_p%d_%d_p%d_%d",
                                t->commodid, s, t->src_price, d, t->dst_price);
          lpx_set_col_name(lp, col, name);
          free(name);
        }
+
+       col++;
       } /* while (tradestodo-- >0) */
       
       /*----- that's done adding these trades to the LP problem -----*/
@@ -317,8 +321,22 @@ void value_route(int nislands, const int *islands) {
   next_s:;
   } /* for (s) */
 
+  if (DEBUGP(lp))
+    lpx_write_cpxlp(lp, (char*)"/dev/stdout");
+
+  int ipr= lpx_interior(lp);
+  assert(ipr==LPX_E_OK);
+
+  if (DEBUGP(lp))
+    lpx_print_ips(lp, (char*)"/dev/stdout");
+
+  assert(lpx_ipt_status(lp) == LPX_T_OPT);
+  double profit= lpx_ipt_obj_val(lp);
+
   lpx_delete_prob(lp);
   lp= 0;
+
+  return profit;
 }
 
 void setup_value(void) {
@@ -333,8 +351,8 @@ void setup_value(void) {
   for (i=0; i<commodstablesz; i++)
     commodstable[i].mass= commodstable[i].volu= -1;
 
-  SQL_MUST( sqlite3_prepare(db,
-     "SELECT commodid,unitmass,unitvolume FROM commods", -1,&sst,0) );
+  SQL_PREPARE(sst,
+             "SELECT commodid,unitmass,unitvolume FROM commods");
   while (SQL_STEP(sst)) {
     int id= sqlite3_column_int(sst,0);
     assert(id>=0 && id<commodstablesz);
@@ -343,31 +361,29 @@ void setup_value(void) {
   }
   sqlite3_finalize(sst);
 
-  SQL_MUST( sqlite3_prepare(db,
-     " SELECT dist from dists where aiid=? and biid=?",
-                           -1, &ss_ipair_dist, 0) );
-
-  SQL_MUST( sqlite3_prepare(db,
-     "SELECT DISTINCT\n"
-     " sell.commodid           commodid,\n"
-     " sell.price              src_price,\n"
-     " buy.price               dst_price\n"
-     " FROM sell JOIN buy\n"
-     "   ON sell.commodid = buy.commodid\n"
-     "  AND buy.price > sell.price\n"
-     " WHERE sell.islandid=?\n"
-     "   AND buy.islandid=?",
-                           -1, &ss_ipair_trades, 0) );
-
-#define BS(bs)                                         \
-  SQL_MUST( sqlite3_prepare(db,                                \
-     "SELECT\n"                                                \
-     " sum(qty)\n"                                     \
-     " FROM " #bs "\n"                                 \
-     " WHERE islandid=?\n"                             \
-     "   AND commodid=?\n"                             \
-     "   AND price=?",                                 \
-                           -1, &ss_ite_##bs, 0) );
+  SQL_PREPARE(ss_ipair_dist,
+             " SELECT dist FROM dists\n"
+             "  WHERE aiid=? and biid=?");
+
+  SQL_PREPARE(ss_ipair_trades,
+             "SELECT DISTINCT\n"
+             " sell.commodid           commodid,\n"
+             " sell.price              src_price,\n"
+             " buy.price               dst_price\n"
+             " FROM sell JOIN buy\n"
+             "   ON sell.commodid = buy.commodid\n"
+             "  AND buy.price > sell.price\n"
+             " WHERE sell.islandid=?\n"
+             "   AND buy.islandid=?");
+
+#define BS(bs)                                 \
+  SQL_PREPARE(ss_ite_##bs,                     \
+             "SELECT\n"                        \
+             " sum(qty)\n"                     \
+             " FROM " #bs "\n"                 \
+             " WHERE islandid=?\n"             \
+             "   AND commodid=?\n"             \
+             "   AND price=?");
   BS(buy)
   BS(sell)
 #undef BS