chiark / gitweb /
WIP create GLPK thing
authorIan Jackson <ian@liberator.(none)>
Tue, 29 Sep 2009 17:57:35 +0000 (18:57 +0100)
committerIan Jackson <ian@liberator.(none)>
Tue, 29 Sep 2009 17:57:35 +0000 (18:57 +0100)
yarrg/rsvalue.c

index 8bdddae..c2cab43 100644 (file)
@@ -41,6 +41,7 @@ static IslandPair *ipair_get(int si, int di) {
   int inblock= TRADES_PER_BLOCK;
   TradesBlock *block= 0;
 
+  debugf("VALUE ipair_get(%d,%d) running...\n", si,di);
   SQL_MUST( sqlite3_bind_int(ss_ipair, 1, si) );
   SQL_MUST( sqlite3_bind_int(ss_ipair, 2, di) );
 
@@ -67,16 +68,68 @@ static IslandPair *ipair_get(int si, int di) {
 
 void value_route(int nislands, const int *islands) {
   int s,d;
-  
+
+  /* We need to construct the LP problem.  GLPK talks
+   * about rows and columns, which are numbered from 1.
+   *
+   * Each column is a `structural variable' ie one of the entries in
+   * the objective function.  In our case the set of structural
+   * variable is, for each visit, the set of Trades which collect at
+   * that island.  (We use `visit' to mean `specific visit to an
+   * island' so if an island appears more than once so do its trades.)
+   * We don't need to worry about crossing with all the possible
+   * delivery locations as we always deliver on the first visit.
+   * We will call such a structural variable a Flow, for brevity.
+   *
+   * We iterate over the possible Flows adding them as columns as we
+   * go, and also adding their entries to the various constraints.
+   *
+   * Each row is an `auxiliary variable' ie one of the constraints.
+   * We have two kinds of constraint:
+   *   - mass/volume/capital: one constraint for each sailed leg
+   *       (unless relevant constraint is not satisfied)
+   *   - quantity of commodity available for collection
+   *       or delivery at particular price and island
+   * The former are numbered predictably: we have first all the mass
+   * limits, then all the volume limits, then all the capital limits
+   * (as applicable) - one for each leg, ie one for each entry
+   * in islands except the first.
+   *
+   * The latter are added as needed and the row numbers are stored in
+   * a data structure for later reuse.
+   */
+
   for (s=0; s<nislands; s++) {
+    int si= islands[s];
     for (d=s; d<nislands; d++) {
-      ipair_get(islands[s], islands[d]);
+      int di= islands[d];
+      int already_d;
+      for (already_d=s+1; already_d<d; already_d++)
+       if (islands[already_d] == di)
+         /* visited this island already since we left s */
+         goto next_d;
+      if (d>s && di==si)
+       /* route has returned to s, no need to think more about this */
+       goto next_d;
+      
+      IslandPair *ip= ipair_get(islands[s], islands[d]);
+      TradesBlock *block= ip->trades;
+      int ntrades= ip->ntrades;
+      int inblock= 0;
+      while (ntrades-- >0) {
+       if (inblock >= TRADES_PER_BLOCK) {
+         block= block->next;
+         inblock= 0;
+       }
+       Trade *t= &block->t[inblock++];
+
+       debugf("  TRADE %d#%d..%d#%d %d %d-%d\n",
+              si,s, di,d, t->commodid, t->src_price, t->dst_price);
+       
+      }
     }
+    next_d:;
   }
-
-  //char *tail;
-  //struct sqlite_vm *sth;
-  //r= sqlite_compile(db, stmt, &tail, &sth, 
 }
 
 void setup_value(void) {