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 >
Wrap
C/C++ Source or Header
|
1989-09-16
|
14KB
|
412 lines
/*****************************************************************************
* Modul : main.c *
* Zweck : Simplexalgorithmus *
* Autor : Stefan Förster *
* *
* Datum | Version | Bemerkung *
* -----------|---------|--------------------------------------------------- *
* 14.03.1989 | 1.0 | *
* 15.03.1989 | | Zeitmessung mittels CurrentTime() *
* 17.03.1989 | 1.1 | SetTaskPri() jetzt korrekt *
* | | min cTx zugelassen *
* 18.03.1989 | 1.2 | Optional Ausgabe an ein File möglich (-f) *
* 06.05.1989 | 1.3 | BUG in Phase I behoben (TryPivot()) *
* 09.05.1989 | | BUG in Phase II behoben (PhaseII()) *
* | | Neue Funktion PrintTime() + Zeitmessung geändert *
* 20.05.1989 | 1.4 | Bessere Ausgabe bei VERBOSE ON *
* | | Neues Kommando "INVERT" *
* | | Kommando "VERBOSE" erweitert: VERBOSE [N] *
* | | Neues Kommando "PRICE" *
* | | Neues Kommando "MINIMIZE" *
* | | 'bsum' als globale Variable für PhaseI() definiert *
* 21.07.1989 | | mpsx.c: Nach NAME jetzt max. 33 Zeichen möglich. *
* 06.08.1989 | 1.5 | Überflüssige Parameter gestrichen *
* 07.08.1989 | | Ein-/Ausgabe in eigenem (NEW)CON:-window *
* | | DEFAULT-Option *
*****************************************************************************/
IMPORT USHORT PhaseI(), PhaseII();
IMPORT BOOL MPSX(), SearchExpr();
IMPORT VOID GetInput();
IMPORT SHORT GetExpr();
IMPORT VOID GiveMemBack(), GetRidOfLists(), PrintError(), Cap();
IMPORT VOID CurrentTime(), *OpenLibrary(), SetTaskPri(), fclose();
IMPORT struct Task *FindTask();
IMPORT FILE *freopen();
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
DOUBLE INFINITE = 1.0/0.0; /* IEEE: NAN (Not A Number) */
#ifdef PAL
TEXT version[] = "NEWCON:0/11/640/245/ASimplex Version 1.5";
#else
TEXT version[] = "NEWCON:0/11/640/189/ASimplex Version 1.5";
#endif
TEXT comment[] = "THE Amiga Simplex Program\n(c) 06.02.-07.08.1989\n\
Stefan Förster";
TEXT reverse[] = "\033[0;0H\033[41;32m\033[J";
FILE *file[2] = { NULL }, *con = NULL;
TEXT symbols[NUM_SYMBOLS][MAX_STRLEN+1];
BOOL minimize = _FALSE; /* _TRUE, falls Zielfunktion minimiert wird */
BOOL global_minimize = _FALSE;
LONG invert_freq = INVERT_FREQUENCY, verbose_freq = 1L;
USHORT method = MIXED;
DOUBLE bsum; /* für PhaseI() */
ITEMPTR list[NUM_LISTS];
TEXT args[BUFFER], line[BUFFER];
SHORT m, n, *B = NULL, *Nq = NULL, *Nminus = NULL;
DOUBLE c0, c0start;
DOUBLE *A = NULL, *AB1 = NULL, *b = NULL, *b2q = NULL;
DOUBLE *c = NULL, *c2 = NULL, *upper = NULL, *lower = NULL;
DOUBLE *x = NULL, *cq = NULL, *pi = NULL, *dq = NULL, *help = NULL;
STRPTR errors[] = {
(STRPTR)"Invalid arguments for \"load\"",
(STRPTR)"Identifier too long",
(STRPTR)"Identifier declared twice",
(STRPTR)"Unknown Identifier",
(STRPTR)"Sections have to start in column 1",
(STRPTR)"Section defined twice",
(STRPTR)"Unknown section",
(STRPTR)"Illegal order of sections",
(STRPTR)"Missing NAME-section (1st section) or NAME-section empty",
(STRPTR)"Missing ROWS-section (2nd section) or ROWS-section empty",
(STRPTR)"Missing goal or goal not found",
(STRPTR)"Missing COLUMNS-section (3rd section) or COLUMNS-section empty",
(STRPTR)"Missing RHS-section (4th section)",
(STRPTR)"Missing ENDATA-section (last section)",
(STRPTR)"Constraint must be of type N, E, L or G",
(STRPTR)"Bound must be of type UP or LO",
(STRPTR)"Lower bound > upper bound",
(STRPTR)"Expression in RANGES belongs to a \"E\"-constraint",
(STRPTR)"Can\'t find necessary expression in this line",
(STRPTR)"File-name too long",
(STRPTR)"Can\'t open file for read access",
(STRPTR)"Can\'t open file for write access",
(STRPTR)"End-of-file reached",
(STRPTR)"Not enough memory",
(STRPTR)"FATAL ERROR (This error should not occur, reboot system!)"
};
main()
{
SHORT start, stop, length, i;
BOOL end = _FALSE;
USHORT verbose = 0, result;
TEXT ch;
STRPTR sptr;
ULONG iter1, iter2, sec1, sec2, micro1, micro2;
LONG pri = 0L;
SHORT atoi();
VOID PrintSolution(), PrintTime(), Leave(), OpenAll();
OpenAll();
FOREVER {
printf(">> ");
GetInput(args);
Cap(args,0,BUFFER);
if(SearchExpr(args,&start,&stop)) {
length = GetExpr(line,args,start,stop);
if(strcmp(line,"HELP") == 0) {
puts(" HELP");
puts(" LOAD <file> [-cGOAL] [-bRHS] [-rRANGE] [-uBOUND] [-m] \
[-fFILE]");
puts(" VERBOSE [N]");
puts(" INVERT [N]");
puts(" PRICE [MIXED|CYCL|STEEP]");
puts(" MINIMIZE");
puts(" PRIORITY [N]");
puts(" DEFAULT");
puts(" QUIT");
}
else if(strcmp(line,"QUIT") == 0) {
do {
printf("?? Really [Y,N] ? ");
GetInput(args);
Cap(args,0,BUFFER);
if(!SearchExpr(args,&start,&stop)) start = 0;
} while((ch = *(args+start))!='N' && ch!='Y');
if(ch == 'Y') Leave("");
}
else if(strcmp(line,"VERBOSE") == 0) {
sptr = args+stop+1;
if(SearchExpr(sptr,&start,&stop)) {
verbose = VERBOSE;
length = GetExpr(line,sptr,start,stop);
verbose_freq = (LONG)atoi(line);
if(verbose_freq < 1L) verbose_freq = 1L;
}
else verbose = verbose ? 0 : VERBOSE;
printf(" VERBOSE %ld O%s\n",verbose_freq, verbose ? "N" : "FF");
}
else if(strcmp(line,"INVERT") == 0) {
sptr = args+stop+1;
if(SearchExpr(sptr,&start,&stop)) {
length = GetExpr(line,sptr,start,stop);
invert_freq = (LONG)atoi(line);
if(invert_freq <= 0L) invert_freq = 0L;
printf(" Changed invert frequency to %ld.\n",invert_freq);
}
else printf(" Current invert frequency is %ld.\n",invert_freq);
}
else if(strcmp(line,"PRICE") == 0) {
sptr = args+stop+1;
if(SearchExpr(sptr,&start,&stop)) {
length = GetExpr(line,sptr,start,stop);
if(strcmp(line,"MIXED") == 0) method = MIXED;
else if(strcmp(line,"CYCL") == 0) method = CYCL;
else if(strcmp(line,"STEEP") == 0) method = STEEP;
printf(" Changed price method to ");
}
else printf(" Current price method is ");
switch(method) {
case MIXED: puts("MIXED.");
break;
case CYCL : puts("CYCL.");
break;
case STEEP: puts("STEEP.");
break;
}
}
else if(strcmp(line,"MINIMIZE") == 0) {
global_minimize = !global_minimize;
printf(" GLOBAL MINIMIZE O%s.\n", global_minimize ? "N" : "FF");
}
else if(strcmp(line,"PRIORITY") == 0) {
sptr = args+stop+1;
if(SearchExpr(sptr,&start,&stop)) {
length = GetExpr(line,sptr,start,stop);
pri = (LONG)atoi(line);
if(pri<0L) pri = 0L;
if(pri>20L) pri = 20L;
SetTaskPri(FindTask((STRPTR)0),pri);
printf(" Changed task priority to %ld.\n",pri);
}
else printf(" Current task priority is %ld.\n",pri);
}
else if(strcmp(line,"DEFAULT") == 0) {
SetTaskPri(FindTask((STRPTR)0),0L);
global_minimize = _FALSE;
method = MIXED;
invert_freq = INVERT_FREQUENCY;
verbose = 0;
verbose_freq = 1;
puts(" Changed task priority to 0.");
puts(" Changed price method to MIXED.");
printf(" Changed invert frequency to %ld.\n",INVERT_FREQUENCY);
puts(" GLOBAL MINIMIZE OFF.");
puts(" VERBOSE 1 OFF.");
}
else if(strcmp(line,"LOAD") == 0) {
if(MPSX(args+stop+1)) {
CurrentTime(&sec1,µ1);
if(!verbose) puts("@@ Please wait - calculation.");
iter1 = iter2 = 0L;
result = PhaseI(&m,&n,c,c2,&c0,c0start,verbose,x,cq,pi,dq,
Nminus,help,&iter1);
if(result == NOT_INVERTABLE) {
puts(" Matrix AB is not invertable.");
if(file[1]) fputs(" Matrix AB is not invertable.\n",file[1]);
}
else if(result == UNBOUNDED) {
puts(" PHASE I IS UNBOUNDED. THIS SHOULD NOT OCCUR!!");
if(file[1])
fputs(" PHASE I IS UNBOUNDED. THIS SHOULD NOT OCCUR!!\n",file[1]);
}
else if(result == EMPTY) {
puts(" This problem is not solveable.");
if(file[1]) fputs(" This problem is not solveable.\n",file[1]);
}
else if(result == CLEAR_CUT) PrintSolution();
else {
result = PhaseII(m,n,c,&c0,c0start,verbose|PHASE_II,x,cq,pi,
dq,Nminus,help,&iter2);
if(result == NOT_INVERTABLE) {
puts(" Matrix AB is not invertable.");
if(file[1]) fputs(" Matrix AB is not invertable.\n",file[1]);
}
else if(result == UNBOUNDED) {
puts(" This problem is unbounded.");
if(file[1]) fputs(" This problem is unbounded.\n",file[1]);
}
else PrintSolution();
}
printf("-> %ld iterations needed.\n",iter1+iter2);
if(file[1]) fprintf(file[1],"-> %ld iterations needed.\n",iter1+iter2);
GiveMemBack();
GetRidOfLists();
minimize = _FALSE;
CurrentTime(&sec2,µ2);
PrintTime("-> Solution time = ",sec1,micro1,sec2,micro2,file[1]);
}
if(file[0]) {
fclose(file[0]);
file[0] = NULL;
}
if(file[1]) {
fprintf(file[1],"\f");
fclose(file[1]);
file[1] = NULL;
}
}
else printf(" Unknown command \"%s\".\n",line);
}
} /* FOREVER */
}
/*****************************************************************************
* VOID PrintTime(str,s1,m1,s2,m2,fptr) *
* berechnet die Zeitdifferenz zwischen s2/m2 und s1/m1 (von CurrentTime() *
* ermittelt, und gibt den String str und die Zeitdauer aus; falls fptr!=NULL*
* auch in das file fptr. *
*****************************************************************************/
VOID PrintTime(str,s1,m1,s2,m2,fptr)
STRPTR str;
ULONG s1, m1, s2, m2;
FILE *fptr;
{
LONG h, min, sec, sec100;
sec100 = m2-m1;
sec = s2-s1;
if(sec100 < 0L) {
sec100 += 1000000L;
--sec;
}
sec100 /= 10000L;
h = sec/3600L;
min = (sec-3600L*h)/60;
sec -= 3600L*h+60*min;
printf("%s %3ld : %02ld : %02ld,%02ld\n",str,h,min,sec,sec100);
if(file[1])
fprintf(file[1],"%s %3ld : %02ld : %02ld,%02ld\n",str,h,min,sec,sec100);
}
/*****************************************************************************
* VOID PrintSolution() *
* Ausgabe der Lösung *
*****************************************************************************/
VOID PrintSolution()
{
VOID PrintX();
puts("@@ Solution:\n");
printf(" %-9s = %14.10lg\n",symbols[GOAL],minimize ? -c0 : c0);
PrintX(list[VAR_LIST],stdout);
puts("");
if(file[1]) {
fputs("@@ Solution:\n\n",file[1]);
fprintf(file[1]," %-9s = %14.10lg\n",symbols[GOAL],minimize ? -c0 : c0);
PrintX(list[VAR_LIST],file[1]);
fputs("\n",file[1]);
}
}
/*****************************************************************************
* VOID PrintX() *
* Gibt das Ergebnis der Berechnungen aus. *
*****************************************************************************/
VOID PrintX(ptr,fptr)
ITEMPTR ptr;
FILE *fptr;
{
if(ptr) {
PrintX(ptr->next,fptr);
fprintf(fptr," %-9s = %14.10lg\n",ptr->string,x[ptr->nr-1]);
}
}
/*****************************************************************************
* VOID OpenAll() *
* Öffnen der Bibliotheken und des (NEW)CON: - windows. *
*****************************************************************************/
VOID OpenAll()
{
VOID Leave();
if(!(IntuitionBase = OpenLibrary("intuition.library",0L)))
Leave("Can't find \"intuition.library\"!");
if(!(GfxBase = OpenLibrary("graphics.library",0L)))
Leave("Can't find \"graphics.library\"!");
if(!(con = freopen(version,"w+",stdout)) &&
!(con = freopen(version+3,"w+",stdout)) )
Leave("Can't open (NEW)CON: - window!");
printf("%s\033[1m%s\n%s\033[0m\033[41;32m\n\n",reverse,version+20,comment);
}
/*****************************************************************************
* VOID Leave() *
* Verlassen des Programms *
*****************************************************************************/
VOID Leave(str)
STRPTR str;
{
if(con) fclose(con);
if(GfxBase) CloseLibrary(GfxBase);
if(IntuitionBase) CloseLibrary(IntuitionBase);
fprintf(stderr,"\n%s\n\n",str);
exit(0);
}