home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff250.lzh / ASimplex / source / main.c next >
C/C++ Source or Header  |  1989-09-16  |  14KB  |  412 lines

  1. /*****************************************************************************
  2.  * Modul                : main.c                                             *
  3.  * Zweck                : Simplexalgorithmus                                 *
  4.  * Autor                : Stefan Förster                                     *
  5.  *                                                                           *
  6.  * Datum      | Version | Bemerkung                                          *
  7.  * -----------|---------|--------------------------------------------------- *
  8.  * 14.03.1989 | 1.0     |                                                    *
  9.  * 15.03.1989 |         | Zeitmessung mittels CurrentTime()                  *
  10.  * 17.03.1989 | 1.1     | SetTaskPri() jetzt korrekt                         *
  11.  *            |         | min cTx zugelassen                                 *
  12.  * 18.03.1989 | 1.2     | Optional Ausgabe an ein File möglich (-f)          *
  13.  * 06.05.1989 | 1.3     | BUG in Phase I behoben (TryPivot())                *
  14.  * 09.05.1989 |         | BUG in Phase II behoben (PhaseII())                *
  15.  *            |         | Neue Funktion PrintTime() + Zeitmessung geändert   *
  16.  * 20.05.1989 | 1.4     | Bessere Ausgabe bei VERBOSE ON                     *
  17.  *            |         | Neues Kommando "INVERT"                            *
  18.  *            |         | Kommando "VERBOSE" erweitert: VERBOSE [N]          *
  19.  *            |         | Neues Kommando "PRICE"                             *
  20.  *            |         | Neues Kommando "MINIMIZE"                          *
  21.  *            |         | 'bsum' als globale Variable für PhaseI() definiert *
  22.  * 21.07.1989 |         | mpsx.c: Nach NAME jetzt max. 33 Zeichen möglich.   *
  23.  * 06.08.1989 | 1.5     | Überflüssige Parameter gestrichen                  *
  24.  * 07.08.1989 |         | Ein-/Ausgabe in eigenem (NEW)CON:-window           *
  25.  *            |         | DEFAULT-Option                                     *
  26.  *****************************************************************************/
  27.  
  28.  
  29.  
  30. IMPORT USHORT         PhaseI(), PhaseII();
  31. IMPORT BOOL           MPSX(), SearchExpr();
  32. IMPORT VOID           GetInput();
  33. IMPORT SHORT          GetExpr();
  34. IMPORT VOID           GiveMemBack(), GetRidOfLists(), PrintError(), Cap();
  35. IMPORT VOID           CurrentTime(), *OpenLibrary(), SetTaskPri(), fclose();
  36. IMPORT struct Task    *FindTask();
  37. IMPORT FILE           *freopen();
  38.  
  39. struct IntuitionBase  *IntuitionBase = NULL;
  40. struct GfxBase        *GfxBase = NULL;
  41.  
  42. DOUBLE    INFINITE = 1.0/0.0;  /* IEEE: NAN (Not A Number) */
  43.  
  44.  
  45. #ifdef PAL
  46. TEXT    version[] = "NEWCON:0/11/640/245/ASimplex Version 1.5";
  47. #else
  48. TEXT    version[] = "NEWCON:0/11/640/189/ASimplex Version 1.5";
  49. #endif
  50.  
  51. TEXT    comment[] = "THE Amiga Simplex Program\n(c) 06.02.-07.08.1989\n\
  52. Stefan Förster";
  53.  
  54. TEXT    reverse[] = "\033[0;0H\033[41;32m\033[J";
  55.  
  56. FILE    *file[2] = { NULL }, *con = NULL;
  57.  
  58. TEXT    symbols[NUM_SYMBOLS][MAX_STRLEN+1];
  59. BOOL    minimize = _FALSE; /* _TRUE, falls Zielfunktion minimiert wird */
  60. BOOL    global_minimize = _FALSE;
  61. LONG    invert_freq = INVERT_FREQUENCY, verbose_freq = 1L;
  62. USHORT  method = MIXED;
  63. DOUBLE  bsum; /* für PhaseI() */
  64.  
  65. ITEMPTR list[NUM_LISTS];
  66. TEXT    args[BUFFER], line[BUFFER];
  67.  
  68. SHORT   m, n, *B = NULL, *Nq = NULL, *Nminus = NULL;
  69. DOUBLE  c0, c0start;
  70. DOUBLE  *A = NULL, *AB1 = NULL, *b = NULL, *b2q = NULL;
  71. DOUBLE  *c = NULL, *c2 = NULL, *upper = NULL, *lower = NULL;
  72. DOUBLE  *x = NULL, *cq = NULL, *pi = NULL, *dq = NULL, *help = NULL;
  73.  
  74.  
  75. STRPTR errors[] = {
  76.   (STRPTR)"Invalid arguments for \"load\"",
  77.   (STRPTR)"Identifier too long",
  78.   (STRPTR)"Identifier declared twice",
  79.   (STRPTR)"Unknown Identifier",
  80.   (STRPTR)"Sections have to start in column 1",
  81.   (STRPTR)"Section defined twice",
  82.   (STRPTR)"Unknown section",
  83.   (STRPTR)"Illegal order of sections",
  84.   (STRPTR)"Missing NAME-section (1st section) or NAME-section empty",
  85.   (STRPTR)"Missing ROWS-section (2nd section) or ROWS-section empty",
  86.   (STRPTR)"Missing goal or goal not found",
  87.   (STRPTR)"Missing COLUMNS-section (3rd section) or COLUMNS-section empty",
  88.   (STRPTR)"Missing RHS-section (4th section)",
  89.   (STRPTR)"Missing ENDATA-section (last section)",
  90.   (STRPTR)"Constraint must be of type N, E, L or G",
  91.   (STRPTR)"Bound must be of type UP or LO",
  92.   (STRPTR)"Lower bound > upper bound",
  93.   (STRPTR)"Expression in RANGES belongs to a \"E\"-constraint",
  94.   (STRPTR)"Can\'t find necessary expression in this line",
  95.   (STRPTR)"File-name too long",
  96.   (STRPTR)"Can\'t open file for read access",
  97.   (STRPTR)"Can\'t open file for write access",
  98.   (STRPTR)"End-of-file reached",
  99.   (STRPTR)"Not enough memory",
  100.   (STRPTR)"FATAL ERROR (This error should not occur, reboot system!)"
  101. };
  102.  
  103.  
  104.  
  105.  
  106.  
  107. main()
  108. {
  109.   SHORT   start, stop, length, i;
  110.   BOOL    end = _FALSE;
  111.   USHORT  verbose = 0, result;
  112.   TEXT    ch;
  113.   STRPTR  sptr;
  114.   ULONG   iter1, iter2, sec1, sec2, micro1, micro2;
  115.   LONG    pri = 0L;
  116.   SHORT   atoi();
  117.   VOID    PrintSolution(), PrintTime(), Leave(), OpenAll();
  118.  
  119.  
  120.   OpenAll();
  121.  
  122.   FOREVER {
  123.  
  124.     printf(">> ");
  125.  
  126.     GetInput(args);
  127.     Cap(args,0,BUFFER);
  128.  
  129.     if(SearchExpr(args,&start,&stop)) {
  130.       length = GetExpr(line,args,start,stop);
  131.  
  132.       if(strcmp(line,"HELP") == 0) {
  133.         puts("   HELP");
  134.         puts("   LOAD <file> [-cGOAL] [-bRHS] [-rRANGE] [-uBOUND] [-m] \
  135. [-fFILE]");
  136.         puts("   VERBOSE [N]");
  137.         puts("   INVERT [N]");
  138.         puts("   PRICE [MIXED|CYCL|STEEP]");
  139.         puts("   MINIMIZE");
  140.         puts("   PRIORITY [N]");
  141.         puts("   DEFAULT");
  142.         puts("   QUIT");
  143.       }
  144.  
  145.       else if(strcmp(line,"QUIT") == 0) {
  146.         do {
  147.           printf("?? Really [Y,N] ? ");
  148.           GetInput(args);
  149.           Cap(args,0,BUFFER);
  150.           if(!SearchExpr(args,&start,&stop)) start = 0;
  151.         } while((ch = *(args+start))!='N' && ch!='Y');
  152.         if(ch == 'Y') Leave("");
  153.       }
  154.  
  155.       else if(strcmp(line,"VERBOSE") == 0) {
  156.         sptr = args+stop+1;
  157.         if(SearchExpr(sptr,&start,&stop)) {
  158.           verbose = VERBOSE;
  159.           length = GetExpr(line,sptr,start,stop);
  160.           verbose_freq = (LONG)atoi(line);
  161.           if(verbose_freq < 1L) verbose_freq = 1L;
  162.         }
  163.         else verbose = verbose ? 0 : VERBOSE;
  164.         printf("   VERBOSE %ld O%s\n",verbose_freq, verbose ? "N" : "FF");
  165.       }
  166.  
  167.       else if(strcmp(line,"INVERT") == 0) {
  168.         sptr = args+stop+1;
  169.         if(SearchExpr(sptr,&start,&stop)) {
  170.           length = GetExpr(line,sptr,start,stop);
  171.           invert_freq = (LONG)atoi(line);
  172.           if(invert_freq <= 0L) invert_freq = 0L;
  173.           printf("   Changed invert frequency to %ld.\n",invert_freq);
  174.         }
  175.         else printf("   Current invert frequency is %ld.\n",invert_freq);
  176.       }
  177.  
  178.       else if(strcmp(line,"PRICE") == 0) {
  179.         sptr = args+stop+1;
  180.         if(SearchExpr(sptr,&start,&stop)) {
  181.           length = GetExpr(line,sptr,start,stop);
  182.           if(strcmp(line,"MIXED") == 0)      method = MIXED;
  183.           else if(strcmp(line,"CYCL") == 0)  method = CYCL;
  184.           else if(strcmp(line,"STEEP") == 0) method = STEEP;
  185.           printf("   Changed price method to ");
  186.         }
  187.         else printf("   Current price method is ");
  188.         switch(method) {
  189.           case MIXED: puts("MIXED.");
  190.                       break;
  191.           case CYCL : puts("CYCL.");
  192.                       break;
  193.           case STEEP: puts("STEEP.");
  194.                       break;
  195.         }
  196.       }
  197.  
  198.       else if(strcmp(line,"MINIMIZE") == 0) {
  199.         global_minimize = !global_minimize;
  200.         printf("   GLOBAL MINIMIZE O%s.\n", global_minimize ? "N" : "FF");
  201.       }
  202.  
  203.       else if(strcmp(line,"PRIORITY") == 0) {
  204.         sptr = args+stop+1;
  205.         if(SearchExpr(sptr,&start,&stop)) {
  206.           length = GetExpr(line,sptr,start,stop);
  207.           pri = (LONG)atoi(line);
  208.           if(pri<0L) pri = 0L;
  209.           if(pri>20L) pri = 20L;
  210.           SetTaskPri(FindTask((STRPTR)0),pri);
  211.           printf("   Changed task priority to %ld.\n",pri);
  212.         }
  213.         else printf("   Current task priority is %ld.\n",pri);
  214.       }
  215.  
  216.       else if(strcmp(line,"DEFAULT") == 0) {
  217.         SetTaskPri(FindTask((STRPTR)0),0L);
  218.         global_minimize = _FALSE;
  219.         method = MIXED;
  220.         invert_freq = INVERT_FREQUENCY;
  221.         verbose = 0;
  222.         verbose_freq = 1;
  223.         puts("   Changed task priority to 0.");
  224.         puts("   Changed price method to MIXED.");
  225.         printf("   Changed invert frequency to %ld.\n",INVERT_FREQUENCY);
  226.         puts("   GLOBAL MINIMIZE OFF.");
  227.         puts("   VERBOSE 1 OFF.");
  228.       }
  229.  
  230.       else if(strcmp(line,"LOAD") == 0) {
  231.         if(MPSX(args+stop+1)) {
  232.           CurrentTime(&sec1,µ1);
  233.           if(!verbose) puts("@@ Please wait - calculation.");
  234.           iter1 = iter2 = 0L;
  235.           result = PhaseI(&m,&n,c,c2,&c0,c0start,verbose,x,cq,pi,dq,
  236.                           Nminus,help,&iter1);
  237.           if(result == NOT_INVERTABLE) {
  238.             puts("   Matrix AB is not invertable.");
  239.             if(file[1]) fputs("   Matrix AB is not invertable.\n",file[1]);
  240.           }
  241.  
  242.           else if(result == UNBOUNDED) {
  243.             puts("   PHASE I IS UNBOUNDED. THIS SHOULD NOT OCCUR!!");
  244.             if(file[1])
  245.               fputs("   PHASE I IS UNBOUNDED. THIS SHOULD NOT OCCUR!!\n",file[1]);
  246.           }
  247.  
  248.           else if(result == EMPTY) {
  249.             puts("   This problem is not solveable.");
  250.             if(file[1]) fputs("   This problem is not solveable.\n",file[1]);
  251.           }
  252.  
  253.           else if(result == CLEAR_CUT) PrintSolution();
  254.  
  255.           else {
  256.             result = PhaseII(m,n,c,&c0,c0start,verbose|PHASE_II,x,cq,pi,
  257.                              dq,Nminus,help,&iter2);
  258.             if(result == NOT_INVERTABLE) {
  259.               puts("   Matrix AB is not invertable.");
  260.               if(file[1]) fputs("   Matrix AB is not invertable.\n",file[1]);
  261.             }
  262.             else if(result == UNBOUNDED) {
  263.               puts("   This problem is unbounded.");
  264.               if(file[1]) fputs("   This problem is unbounded.\n",file[1]);
  265.             }
  266.             else PrintSolution();
  267.           }
  268.  
  269.           printf("-> %ld iterations needed.\n",iter1+iter2);
  270.           if(file[1]) fprintf(file[1],"-> %ld iterations needed.\n",iter1+iter2);
  271.           GiveMemBack();
  272.           GetRidOfLists();
  273.           minimize = _FALSE;
  274.           CurrentTime(&sec2,µ2);
  275.           PrintTime("-> Solution time = ",sec1,micro1,sec2,micro2,file[1]);
  276.         }
  277.         if(file[0]) {
  278.           fclose(file[0]);
  279.           file[0] = NULL;
  280.         }
  281.         if(file[1]) {
  282.           fprintf(file[1],"\f");
  283.           fclose(file[1]);
  284.           file[1] = NULL;
  285.         }
  286.       }
  287.  
  288.       else printf("   Unknown command \"%s\".\n",line);
  289.  
  290.     }
  291.  
  292.   } /* FOREVER */
  293.  
  294. }
  295.  
  296.  
  297.  
  298. /*****************************************************************************
  299.  * VOID PrintTime(str,s1,m1,s2,m2,fptr)                                      *
  300.  * berechnet die Zeitdifferenz zwischen s2/m2 und s1/m1 (von CurrentTime()   *
  301.  * ermittelt, und gibt den String str und die Zeitdauer aus; falls fptr!=NULL*
  302.  * auch in das file fptr.                                                    *
  303.  *****************************************************************************/
  304.  
  305. VOID    PrintTime(str,s1,m1,s2,m2,fptr)
  306. STRPTR  str;
  307. ULONG   s1, m1, s2, m2;
  308. FILE    *fptr;
  309.  
  310. {
  311.   LONG  h, min, sec, sec100;
  312.  
  313.   sec100 = m2-m1;
  314.   sec = s2-s1;
  315.   if(sec100 < 0L) {
  316.     sec100 += 1000000L;
  317.     --sec;
  318.   }
  319.   sec100 /= 10000L;
  320.   h = sec/3600L;
  321.   min = (sec-3600L*h)/60;
  322.   sec -= 3600L*h+60*min;
  323.   printf("%s %3ld : %02ld : %02ld,%02ld\n",str,h,min,sec,sec100);
  324.   if(file[1])
  325.     fprintf(file[1],"%s %3ld : %02ld : %02ld,%02ld\n",str,h,min,sec,sec100);
  326. }
  327.  
  328.  
  329.  
  330. /*****************************************************************************
  331.  * VOID PrintSolution()                                                      *
  332.  * Ausgabe der Lösung                                                        *
  333.  *****************************************************************************/
  334.  
  335. VOID    PrintSolution()
  336.  
  337. {
  338.   VOID PrintX();
  339.  
  340.   puts("@@ Solution:\n");
  341.   printf("   %-9s = %14.10lg\n",symbols[GOAL],minimize ? -c0 : c0);
  342.   PrintX(list[VAR_LIST],stdout);
  343.   puts("");
  344.  
  345.   if(file[1]) {
  346.     fputs("@@ Solution:\n\n",file[1]);
  347.     fprintf(file[1],"   %-9s = %14.10lg\n",symbols[GOAL],minimize ? -c0 : c0);
  348.     PrintX(list[VAR_LIST],file[1]);
  349.     fputs("\n",file[1]);
  350.   }
  351. }
  352.  
  353.  
  354.  
  355. /*****************************************************************************
  356.  * VOID PrintX()                                                             *
  357.  * Gibt das Ergebnis der Berechnungen aus.                                   *
  358.  *****************************************************************************/
  359.  
  360. VOID    PrintX(ptr,fptr)
  361.  
  362. ITEMPTR ptr;
  363. FILE    *fptr;
  364.  
  365. {
  366.   if(ptr) {
  367.     PrintX(ptr->next,fptr);
  368.     fprintf(fptr,"   %-9s = %14.10lg\n",ptr->string,x[ptr->nr-1]);
  369.   }
  370. }
  371.  
  372.  
  373. /*****************************************************************************
  374.  * VOID OpenAll()                                                            *
  375.  * Öffnen der Bibliotheken und des (NEW)CON: - windows.                      *
  376.  *****************************************************************************/
  377.  
  378. VOID OpenAll()
  379. {
  380.   VOID Leave();
  381.  
  382.   if(!(IntuitionBase = OpenLibrary("intuition.library",0L)))
  383.     Leave("Can't find \"intuition.library\"!");
  384.   if(!(GfxBase = OpenLibrary("graphics.library",0L)))
  385.     Leave("Can't find \"graphics.library\"!");
  386.  
  387.   if(!(con = freopen(version,"w+",stdout)) &&
  388.      !(con = freopen(version+3,"w+",stdout))  )
  389.     Leave("Can't open (NEW)CON: - window!");
  390.   printf("%s\033[1m%s\n%s\033[0m\033[41;32m\n\n",reverse,version+20,comment);
  391. }
  392.  
  393.  
  394.  
  395. /*****************************************************************************
  396.  * VOID Leave()                                                              *
  397.  * Verlassen des Programms                                                   *
  398.  *****************************************************************************/
  399.  
  400. VOID    Leave(str)
  401.  
  402. STRPTR  str;
  403.  
  404. {
  405.   if(con)           fclose(con);
  406.   if(GfxBase)       CloseLibrary(GfxBase);
  407.   if(IntuitionBase) CloseLibrary(IntuitionBase);
  408.  
  409.   fprintf(stderr,"\n%s\n\n",str);
  410.   exit(0);
  411. }
  412.