home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e065 / 2.ddi / TSPIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  15.2 KB  |  559 lines

  1. /* 5:30 July 7, 1988 TSPIO.c TSP interface routine  */
  2.  
  3. /************************************************************************
  4.  * Copyright(C) 1988-1989 NeuralWare Inc                                *
  5.  * Penn Center West, IV-227, Pittsburgh, PA 15276                       *
  6.  *                                                                      *
  7.  * All rights reserved.  No part of this program may be reproduced,     *
  8.  * stored in a retrieval system, or transmitted, in any form or by any  *
  9.  * means, electronic, mechanical, photocopying, recording or otherwise  *
  10.  * without the prior written permission of the copyright owner,         *
  11.  * NeuralWare, Inc.                                                     *
  12.  ************************************************************************
  13.  */
  14.  
  15. #include "userutl.h"
  16. #ifndef SUN
  17. #ifndef DLC
  18. #include <stdlib.h>
  19. #endif
  20. #endif
  21. #include <string.h>
  22.  
  23. #include "tsp.h"
  24.  
  25. #ifdef MAC
  26. #include  "macuio.redef"
  27. #endif
  28.  
  29. /************************************************************************
  30.  *              
  31.  *  Traveling Sales Person Problem Interface
  32.  *                 
  33.  ************************************************************************
  34.  */
  35.  
  36. #define X 0
  37. #define Y 1
  38.  
  39. #define CITY_WIDTH  3 /* Half width of a displayed city */
  40.  
  41. static  int city_pos[MAX_NUM_CITIES][2]; /* screen positions of cities */
  42. static  int city_stop[MAX_NUM_CITIES];   /* itinerary index */
  43.  
  44. /* window parameters */
  45. static int  xstrt, ystrt, width = {200}, height, xmargin = {20}, ymargin;
  46.  
  47. #define TSP_STEPSIZE  0
  48. #define TSP_NEXTSTEP  1
  49. #define TSP_QUIT  2
  50.  
  51. char  response[100];
  52. static  CITY  cities[MAX_NUM_CITIES], *city_ptr;
  53. static  int num_cities;
  54.  
  55. /* Local menu definitions */
  56. #define STPSZ_STR "Step size: ***"
  57. #define NXTST_STR "Next step"
  58. #define QUIT_STR  "Quit"
  59.  
  60. static GMENU_ITEM TspList[] = {
  61.     { TSP_STEPSIZE, 0, 0 },
  62.     { TSP_NEXTSTEP, 0, 0 },
  63.     { TSP_QUIT,     0, 0 }
  64. };
  65.  
  66. static GMENU  TspMenu  = {
  67.   0,
  68.   3,        /* 3 items */
  69.   2,        /* key */
  70.   0x0000
  71. };
  72.  
  73. static int  xmwdw,ymwdw;    /* menu window position */
  74. static int  stepsize = {10};  /* how often display is updated */
  75. static int  curr_iteration, prev_iteration;
  76.  
  77. extern  double  sqrt( );
  78.  
  79. #ifdef DLC
  80. /* --- prototypes --- */
  81. double  calc_itin( );
  82.   get_line( FILE * );
  83.   disp_itin( int, int );
  84. #endif
  85.  
  86. get_line(fp)
  87. FILE *fp;
  88. {
  89. #ifdef MAC
  90. #define NEWLN 015
  91. #else
  92. #define NEWLN 012
  93. #endif
  94.  
  95.   int i;
  96.   char c;
  97.   int notempty=0;
  98.   
  99.   for (i=0;i<100;i++)
  100.     {
  101.     if ((response[i] = fgetc(fp)) == EOF)
  102.       return EOF;
  103.     if (response[i] == NEWLN) {
  104.       if ( notempty == 0 ) {
  105.         i = -1;
  106.         continue;
  107.       } else break;
  108.     }
  109.     if (response[i] == '!')     /* comment */
  110.       {
  111.       /* skip to line end*/
  112.       while(((c=fgetc(fp)) != NEWLN) && (c != EOF)) ;
  113.       if (c == EOF)
  114.         return EOF;
  115.       if (i == 0 || notempty == 0)
  116.         { /* if at beginning just skip */
  117.         i = -1;
  118.         continue;
  119.         }
  120.       else
  121.         break;  /* return to calling program */
  122.       }
  123.     /* Must be valid to fall through - flag non-empty line */
  124.     if (response[i] > ' ' && response[i] <= 0x7f ) notempty = 1;
  125.     }
  126.   if (i==100)
  127.     return EOF;
  128.   response[i]='\0';
  129.   return 0;
  130. }
  131.  
  132. disp_itin( citycolor, linecolor )
  133. int citycolor;
  134. int linecolor;
  135. {
  136.   int wx, wy, wz;
  137.   
  138.   /* Draw itinerary */
  139.   for (wx = 0; wx < num_cities - 1; ) {
  140.     wy = city_stop[wx++];
  141.     wz = city_stop[wx];
  142.     ug_line( 1, linecolor, 0,
  143.        city_pos[wy][X], city_pos[wy][Y],
  144.        city_pos[wz][X], city_pos[wz][Y], 0 );
  145.   }
  146.   /* Complete the tour */
  147.   wy = city_stop[num_cities - 1];
  148.   wz = city_stop[0];
  149.   ug_line( 1, linecolor, 0,
  150.      city_pos[wy][X], city_pos[wy][Y],
  151.      city_pos[wz][X], city_pos[wz][Y], 0 );
  152.   
  153.   /* Display cities */
  154.   for ( wx=0; wx < num_cities; wx++ )
  155.     ug_boxf( 1, citycolor, 0,
  156.        city_pos[wx][X]-CITY_WIDTH, city_pos[wx][Y]-CITY_WIDTH,
  157.        city_pos[wx][X]+CITY_WIDTH, city_pos[wx][Y]+CITY_WIDTH);
  158. }
  159.  
  160. double  calc_itin( )    /* Calculate length of itinerary */
  161. {
  162.   int   wx, wy, wz;
  163.   double  dt;   /* distance travelled */
  164.   double  xdiff, ydiff;
  165.   
  166.   dt = 0.0;
  167.   
  168.   for (wx = 0; wx < num_cities; ) {
  169.     wy = city_stop[wx++];
  170.     wz = city_stop[wx%num_cities];
  171.     xdiff = cities[wz].xloc - cities[wy].xloc;
  172.     ydiff = cities[wz].yloc - cities[wy].yloc;
  173.     dt += sqrt( xdiff * xdiff + ydiff * ydiff );
  174.   }
  175.   return( dt );
  176. }
  177.  
  178.     
  179. int nocase_strcmp(str1,str2)
  180. char *str1;
  181. char *str2;
  182. {
  183.   int diff;
  184.   int mask;
  185.   
  186.   mask = ~('a' ^ 'A');
  187.   diff = (*str1 & mask) - (*str2 & mask);
  188.   while((*str1 != '\0') && (*str2 != '\0') && (diff == 0))
  189.     {
  190.     diff = (*str1 & mask) - (*str2 & mask);
  191.     str1++;
  192.     str2++;
  193.     }
  194.   return diff;
  195. }
  196. /*   */
  197. /************************************************************************
  198.  *
  199.  *  UsrIO - user I/O routine to handle requests from NWORKS
  200.  *
  201.  ************************************************************************
  202.  */
  203.  
  204. static int AbortFlag  = 0;
  205. static int InitFlag = 0;    /* initialize things flag */
  206.  
  207. int UsrIO()     /* handle NWORKS requests */
  208. {
  209.     int   wx, wy, wz;       /* work indices */
  210.     int   button;      /* mouse interface */
  211.     int   xsize, ysize, ncolor, chrx, chry; /* graphics parameters */
  212.     GMENU_ITEM  *gmip;
  213.     char  *city_fname;        /* city file name */
  214.     int   nlayp, ninp, noutp, ltype;    /* Network parameters */
  215.     char  *csp;         /* Control strategy pointer*/
  216.     float xlow, xhigh, ylow, yhigh, diff, scl;  /* world city params */
  217.     float scrn_ratio;       /* Aspect ratio of screen */
  218.     float maxout;
  219.     FILE *fp;
  220.     char  sp[60];       /* string pointer */
  221.  
  222.     if ( InitFlag == 0 )  {
  223.       TspList[0].text = STPSZ_STR;
  224.       TspList[1].text = NXTST_STR;
  225.       TspList[2].text = QUIT_STR;
  226.       
  227.       TspMenu.item=TspList;
  228.  
  229.       InitFlag = 1;
  230.     }
  231.  
  232.     IORTNCDE = 0;       /* good return for data */
  233.     switch( IOREQCDE ) {
  234.     case RQ_ATTENTION:
  235.   /* This is invoked at the request of the user from the
  236.      execute menu.  It allows parameters to be changed or
  237.      altered.  Any graphics or other interactions are allowable
  238.      as usual for the other options.
  239.   */
  240.   break;
  241.  
  242.     case RQ_LSTART:       /* starting learn */
  243.   /* This tells the user that the program is about to start
  244.      learning.  It is called once for a LEARN ALL, LEARN ONE,
  245.      LEARN N, or LEARN START
  246.   */
  247.   break;
  248.  
  249.     case RQ_LEARNOUT:       /* read desired output */
  250.   /* IODATA points to an empty array of IOCOUNT values.  The
  251.      elements of the array will become the desired outputs for
  252.      training purposes.  These desired outputs correspond to
  253.      the most recent "RQ_LEARNIN" request.
  254.   */
  255.     case RQ_RCLTST:   /* read desired output during recall test */
  256.   /* IODATA points to an empty array of IOCOUNT values.  The
  257.      elements of the array will become the desired outputs for
  258.      recall purposes.  This request is only made during a
  259.      Execute Network/Recall Test.
  260.   */
  261.   break;
  262.  
  263.     case RQ_LEARNRSLT:
  264.   /* IODATA points to an array of IOCOUNT values.  These are the
  265.      output of the network caused by the inputs from RQ_LEARNIN.
  266.   */
  267.   break;
  268.  
  269.     case RQ_RSTART:       /* starting recall */
  270.   /* This tells the user that the program is about to start
  271.      a recall.  It is called once for a RECALL ALL, RECALL ONE,
  272.      RECALL N, or RECALL START.
  273.   */
  274.       AbortFlag = 0;
  275.       /* Read network parameters */
  276.       ug_rdnetinf( &nlayp, &ninp, &noutp, <ype, &csp, &city_fname );
  277.       /* Get city file information */
  278.       if ((fp=fopen(city_fname,"r")) == NULL) {
  279.         PutStr("Cannot find default city file; please enter file name:");
  280.         city_fname = GetStr();
  281.         PutStr("\n");
  282.  
  283.         if ((fp=fopen(city_fname,"r")) == NULL) {
  284.     PutStr("Bad filename\n");
  285.     IORTNCDE = -1;
  286.     AbortFlag = 1;
  287.     return(0);
  288.   }
  289.       }
  290.   do {
  291.     if (get_line(fp) == EOF) {
  292.       PutStr("Unexpected EOF found\n");
  293.       IORTNCDE = -1;
  294.       AbortFlag = 1;
  295.       fclose(fp);
  296.       return(0);
  297.     }
  298.   } while (nocase_strcmp(response,"CITIES") != 0);
  299.     
  300.   num_cities = 0;
  301.   city_ptr = cities;
  302.   while(1) {
  303.     if (get_line(fp) == EOF) break;
  304.     if (nocase_strcmp(response,"DISTANCES") == 0) break;
  305. #ifdef THINK_C
  306.     sscanf(response,"   %s  %Lf %Lf",
  307.      city_ptr->name,
  308.      &city_ptr->xloc,
  309.      &city_ptr->yloc);
  310. #else
  311.     sscanf(response,"   %s  %lf %lf",
  312.      city_ptr->name,
  313.      &city_ptr->xloc,
  314.      &city_ptr->yloc);
  315. #endif
  316.     city_ptr++;
  317.     num_cities++;
  318.   }
  319.  
  320.   fclose(fp);
  321.  
  322.   if ( num_cities * num_cities != noutp ) {
  323.     PutStr("Mismatch between city file and network\n");
  324.     IORTNCDE = -1;
  325.     AbortFlag = 1;
  326.     fclose(fp);
  327.     return(0);
  328.   }
  329.  
  330.   /* Calculate city coordinate extremes */
  331.   city_ptr = cities;
  332.   xlow = xhigh = city_ptr->xloc;
  333.   ylow = yhigh = city_ptr->yloc;
  334.   for ( wx = 1; wx < num_cities; wx++ ) {
  335.     city_ptr++;
  336.     if (xlow > city_ptr->xloc ) xlow = city_ptr->xloc;
  337.     if (xhigh < city_ptr->xloc ) xhigh = city_ptr->xloc;
  338.     if (ylow > city_ptr->yloc ) ylow = city_ptr->yloc;
  339.     if (yhigh < city_ptr->yloc ) yhigh = city_ptr->yloc;
  340.   }
  341.   diff = (xhigh - xlow) - (yhigh - ylow);
  342.  
  343.   if ( diff > 0.0 ) {
  344.     ylow = ylow - diff/2.0;
  345.     yhigh = yhigh + diff/2.0;
  346.   } else {
  347.     xlow = xlow + diff/2.0;
  348.     xhigh = xhigh - diff/2.0;
  349.   }
  350.   scl = xhigh - xlow;
  351.   if ( scl < 0.01 ) scl = 0.01;
  352.   
  353.   /* Get screen parameters */
  354.   ug_gparms( &xsize, &ysize, &ncolor, &chrx, &chry);
  355.   
  356.   /* Assume screen aspect ratio of 4:3 */
  357.   scrn_ratio = (4.0 * ysize) / ( 3.0 * xsize );
  358.   height = width * scrn_ratio;
  359.   ymargin = xmargin * scrn_ratio;
  360.   xstrt = (xsize - width) / 2 - xmargin;
  361.   ystrt = (ysize - height) / 2 - ymargin;
  362.  
  363.   /* Calculate city screen coordinates */
  364.   for ( wx=0, city_ptr=cities; wx < num_cities; wx++, city_ptr++ ) {
  365.     city_pos[wx][X] =
  366.       xmargin + (int) ( (city_ptr->xloc - xlow) * width / scl );
  367.     city_pos[wx][Y] =
  368.       ymargin + (int) ( (city_ptr->yloc - ylow) * height / scl );
  369.   }
  370.  
  371.   if ( ncolor < 8 ) {
  372.     gm_intcolor = 1;
  373.     gm_txtcolor = 0;
  374.     gm_outcolor = 0;
  375.   } else {
  376.     gm_intcolor = 7;
  377.     gm_txtcolor = 4;
  378.     gm_outcolor = 0;
  379.   }
  380.  
  381.   InitGMenu( &TspMenu, chrx, chry );
  382.   xmwdw = (xsize - TspMenu.x1) / 2;
  383.   ymwdw = ystrt / 2;
  384.   TspMenu.x0 = 0; /* Menu position relative to window */
  385.   TspMenu.y0 = 0;
  386.   
  387.   /* Unlock all menu items */
  388.   for (gmip = TspMenu.item, wx = 0; wx < TspMenu.num_items;
  389.          gmip++, wx++ )
  390.       gmip->flag &= ~GM_LOCKED;
  391.  
  392.         /* Other initializations */
  393.   sprintf( sp, "%3ld", (long)stepsize );
  394.   strncpy( &TspList[TSP_STEPSIZE].text[11], sp, 3 );
  395.   for ( wx = 0; wx < num_cities; wx++ ) city_stop[wx] = wx;
  396.   curr_iteration = prev_iteration = 0;
  397.  
  398.   /* define windows */
  399.   ug_window( 1, gm_intcolor, xstrt, ystrt,
  400.        xstrt + 2*xmargin + width - 1,
  401.        ystrt + 2*ymargin + height - 1 );
  402.   ug_boxf( 1, gm_outcolor, 0, 0, 0,
  403.      2*xmargin + width - 1,
  404.      2*ymargin + height - 1 );
  405.   ug_boxf( 1, gm_intcolor, 0, 3, 3,
  406.      2*xmargin + width - 4,
  407.      2*ymargin + height - 4 );
  408.  
  409.  
  410.   ug_window( TspMenu.key, gm_intcolor, xmwdw, ymwdw,
  411.        xmwdw + TspMenu.x1 + 2, ymwdw + TspMenu.y1 + 2);
  412.  
  413.   DispGMenu( &TspMenu );
  414.  
  415.   break;
  416.  
  417.     case RQ_LEARNIN:        /* read training input */
  418.   /* IODATA points to an empty array of IOCOUNT elements.  The
  419.      values placed in this array by the user will become the
  420.      inputs to the network for training purposes.
  421.   */
  422.   break;
  423.       
  424.     case RQ_READ:       /* read test data */
  425.   /* IODATA points to an empty array of IOCOUNT values.  The
  426.      user must fill in these values.  The elements of the
  427.      array will become the "sum" of the inputs to the input
  428.      layer of processing elements.
  429.   */ 
  430.   break;
  431.  
  432.     case RQ_WRSTEP:       /* write interim results */
  433.   /* each recall cycle for the Hopfield and BAM control strategies,
  434.      the intermediate output is made available to userio to test
  435.      for convergence or other desired states.  This option is
  436.      not used for other control strategies.
  437.   */
  438.   if (AbortFlag) {
  439.     IORTNCDE = -1;
  440.     return(0);
  441.   } 
  442.   curr_iteration++;
  443.   if( curr_iteration - prev_iteration == stepsize ) {
  444.     prev_iteration = curr_iteration;
  445.     sprintf( sp, "Iteration number %3ld\n", (long)curr_iteration );
  446.     PutStr( sp );
  447.  
  448.     disp_itin( gm_intcolor, gm_intcolor ); /* Erase itinerary */
  449.     /* Calculate city stops */
  450.     for ( wx = 0; wx < num_cities; wx++ ) {
  451.       maxout = -1.0;
  452.       for ( wy = wx, wz = 0; wz < num_cities; wz++, wy += num_cities) {
  453.         if ( IODATA[wy] >= maxout ) {
  454.     maxout = IODATA[wy];
  455.     city_stop[wx] = wz;
  456.         }
  457.       }
  458.     }
  459.     disp_itin( gm_txtcolor, gm_txtcolor );
  460.     sprintf( sp, "Length of itinerary = %f\n", calc_itin( ) );
  461.     PutStr( sp );
  462.  
  463.     for ( ; ; ) 
  464.       {
  465.         while ( (gmip=LookGMenu(&TspMenu,&button )) == (GMENU_ITEM *) 0) ;
  466.         switch( gmip->code ) 
  467.     {
  468.     case TSP_STEPSIZE:
  469. #ifdef MAC
  470.       if (button == MBUT_LEFT)
  471. #else
  472.       if (button == MBUT_RIGHT)
  473. #endif
  474.         stepsize++;
  475. #ifdef MAC
  476.       if (button == MBUT_RIGHT)
  477. #else
  478.       if (button == MBUT_LEFT) 
  479. #endif
  480.         {
  481.           stepsize--;
  482.           if ( stepsize < 1 ) stepsize = 1;
  483.         }
  484.       if (button == MBUT_LEFT || button == MBUT_RIGHT) 
  485.         {
  486.           sprintf( sp, "%3ld", (long)stepsize );
  487.           strncpy( &TspList[TSP_STEPSIZE].text[11], sp, 3 );
  488.           DispGItem( &TspMenu, gmip, gm_intcolor, gm_txtcolor );
  489.         }
  490.       break;
  491.     case TSP_NEXTSTEP:
  492.       if ( button == MBUT_RIGHT || button == MBUT_LEFT ) 
  493.         {
  494.           goto end_wr;
  495.         }
  496.       break;
  497.     case TSP_QUIT:
  498.       if ( button == MBUT_RIGHT || button == MBUT_LEFT ) 
  499.         {
  500.           IORTNCDE = -1;
  501.           goto end_wr;
  502.         }
  503.       break;
  504.     }
  505.       }
  506.         }
  507. end_wr:
  508.   break;
  509.  
  510.     case RQ_WRITE:        /* write out results */
  511.   /* IODATA points to an array of IOCOUNT "float" type values.
  512.      The values are the outputs of the top-most layer of the
  513.      network.
  514.   */
  515.  
  516.   if (AbortFlag) {
  517.     IORTNCDE = -1;
  518.     return(0);
  519.   } 
  520.     /* Calculate final itinerary */
  521.     for ( wx = 0; wx < num_cities; wx++ ) {
  522.       maxout = -1.0;
  523.       for ( wy = wx, wz = 0; wz < num_cities; wz++, wy += num_cities) {
  524.         if ( IODATA[wy] >= maxout ) {
  525.     maxout = IODATA[wy];
  526.     city_stop[wx] = wz;
  527.         }
  528.       }
  529.     }
  530.     disp_itin( gm_txtcolor, gm_txtcolor );
  531.     PutStr("Final Itinerary\n");
  532.     TspList[TSP_STEPSIZE].flag |= GM_LOCKED;
  533.     TspList[TSP_NEXTSTEP].flag |= GM_LOCKED;
  534.   
  535.     for ( ; ; ) {
  536.       while ( (gmip=LookGMenu(&TspMenu,&button )) == (GMENU_ITEM *) 0) ;
  537.         if ( button == MBUT_RIGHT || button == MBUT_LEFT ) {
  538.           IORTNCDE = -1;
  539.           goto end_write;
  540.         }
  541.     }
  542. end_write:
  543.   break;
  544.  
  545.  
  546.     case RQ_TERM:       /* terminate interface */
  547.   /* close any files which may be open.  Deallocate any memory
  548.      which was allocated.  (This is VERY VERY important.  If
  549.      allocated memory is NOT released, dos memory will become
  550.      fragmented and it will become necessary to reboot.
  551.   */
  552.  
  553.   PutStr( "bye bye" );
  554.   break;
  555.     }
  556.  
  557.     return;
  558. }
  559.