home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume07 / minit < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  24.1 KB

  1. From decwrl!ucbvax!tut.cis.ohio-state.edu!brutus.cs.uiuc.edu!wuarchive!wugate!uunet!allbery Thu Aug  3 08:51:40 PDT 1989
  2. Article 999 of comp.sources.misc:
  3. Path: decwrl!ucbvax!tut.cis.ohio-state.edu!brutus.cs.uiuc.edu!wuarchive!wugate!uunet!allbery
  4. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5. Newsgroups: comp.sources.misc
  6. Subject: v07i107: A Linear Programming Package for comp.sources.misc
  7. Message-ID: <61722@uunet.UU.NET>
  8. Date: 28 Jul 89 01:23:23 GMT
  9. Sender: allbery@uunet.UU.NET
  10. Reply-To: badri@ee.rochester.edu (Badri Lokanathan )
  11. Lines: 1042
  12. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  13.  
  14. Posting-number: Volume 7, Issue 107
  15. Submitted-by: badri@ee.rochester.edu (Badri Lokanathan )
  16. Archive-name: minit
  17.  
  18. I am enclosing the following Linear Programming package for submission
  19. to comp.sources.misc. I keep seeing postings to comp.sources.wanted
  20. for such a package, so I figure some folks out there will have use for it!
  21.  
  22. Badri Lokanathan
  23. # Shell archive; cut here and unpack with /bin/sh
  24. echo x - README
  25. sed 's/^X//' >README <<'*-*-END-of-README-*-*'
  26. XThis bundle contains a linear programming package based on the dual
  27. Xsimplex method. The original code was given in Collected Algorithms
  28. Xfrom CACM (1968) in algol 60 by Rudolfo Salazar and Subrata Sen. The
  29. Xevaluators of this algorithm suggested some fixes that have also been
  30. Xincorporated.
  31. XI translated it into C and have been using it for sometime now without
  32. Xany problems. The code consists of two parts:
  33. X
  34. X(1) A function called minit_space_handler to initialize arrays by
  35. X    mallocing the appropriate amount of space, and minit, the actual
  36. X    LP solver. These routines can be invoked directly by another
  37. X    package. Both are in file minit.c
  38. X
  39. X(2) A front end to use the minit routines stand alone. Usage is
  40. X    documented in the man page.
  41. X    
  42. XIf a laser printer is available, the man page may be printed as
  43. X    eqn minit.1 | troff -t -man | lpr -t -Pwhatever
  44. XOtherwise
  45. X    nroff -man minit.1
  46. X
  47. XThe implementation has been tested on a VAX 750 under BSD 4.2/4.3
  48. Xand Sun-3's with OS 3.5 and 4.0.3.
  49. X
  50. XBadri Lokanathan
  51. XDept. of Electrical Engineering
  52. XUniversity of Rochester
  53. *-*-END-of-README-*-*
  54. echo x - Makefile
  55. sed 's/^X//' >Makefile <<'*-*-END-of-Makefile-*-*'
  56. XCFLAGS    = -O -c
  57. X#DEFS    = -DDEBUG
  58. XDEFS    =
  59. X
  60. X.c.o:
  61. X    cc ${CFLAGS} ${DEFS} $*.c
  62. X
  63. Xminit: minit.o minmain.o
  64. X    cc -O -o minit minit.o minmain.o
  65. *-*-END-of-Makefile-*-*
  66. echo x - minit.1
  67. sed 's/^X//' >minit.1 <<'*-*-END-of-minit.1-*-*'
  68. X.TH MINIT 1 "14 Dec 1988" "UR VLSI"
  69. X.SH NAME
  70. Xminit \- an efficient Linear Programming package
  71. X.SH SYNOPSIS
  72. X\fBminit\fP [\fB-p\fPprec] [\fB-i\fP[filename]]
  73. X.SH DESCRIPTION
  74. X.I Minit
  75. Xsolves a Linear Programming problem of n variables and m constraints,
  76. Xthe last p of which are equality constraints by the dual simplex method.
  77. XThe problem statement is
  78. X.sp 1
  79. X.if t \{
  80. X.EQ I
  81. XMaximize ~~z ~=~ c bar sup T ~ x bar ~~~~subject ~~"to"
  82. X.EN
  83. X.EQ I
  84. Xbold A x bar ~<=~ b, bar
  85. X~~~~x bar ~>=~ 0 bar
  86. X.EN
  87. X\}
  88. X.if n \{
  89. X.RS
  90. X.nf
  91. XMaximize z = cX
  92. Xsubject to
  93. XAX <= b
  94. XX >= 0,
  95. Xwhere
  96. X\(bu c is a (1*n) row vector
  97. X\(bu X is a (n*1) column vector
  98. X\(bu A is a (m*n) matrix
  99. X\(bu b is a (m*1) column vector.
  100. X.RE
  101. X.fi
  102. X\}
  103. X.SH OPTIONS
  104. X.IP "-p"
  105. XThe following integer specifies the precision (number of decimal places)
  106. Xof the output.
  107. XThe default is free-format.
  108. X.IP "-i"
  109. XThe following argument is the name of the input file.
  110. XIf no filename is specified,
  111. Xminit goes into interactive mode and prompts for input.
  112. X.LP
  113. XIf the -i option is omitted,
  114. Xminit takes input (in the appropriate format) from standard input. 
  115. X.SH EXAMPLE
  116. XAn example with 4 variables, 2 inequality constraints and 1
  117. Xequality constraint follows. The input corresponds to the problem
  118. X.sp 1
  119. X.if t \{
  120. X.EQ I
  121. XMaximize ~~6 x sub 1 ~+~ x sub 2 ~-~ x sub 3 ~-~ x sub 4
  122. X~~~~subj. ~~"to"
  123. X.EN
  124. X.br
  125. X.EQ I
  126. Xx sub 1 ~+~ 2 x sub 2 ~+~ x sub 3 ~+~ x sub 4 mark ~<=~ 5
  127. X.EN
  128. X.br
  129. X.EQ I
  130. X3 x sub 1 ~+~ x sub 2 ~-~ x sub 3 lineup ~<=~ 8
  131. X.EN
  132. X.br
  133. X.EQ I
  134. Xx sub 2 ~+~ x sub 3 ~+~ x sub 4  lineup ~=~ 1
  135. X.EN
  136. X.br
  137. X.EQ I
  138. Xx sub i ~>=~ 0, ~~i ~=~ 1 ,..., 4
  139. X.EN
  140. X\}
  141. X.if n \{
  142. X.RS
  143. X.nf
  144. XMaximize 6x1 + x2 - x3 - x4 subj. to
  145. X
  146. Xx1 + 2x2 + x3 + x4 <= 5
  147. X3x1 + x2 - x3      <= 8
  148. X      x2 + x3 + x4  = 1
  149. X
  150. Xx1, x2, x3, x4 >= 0
  151. X.RE
  152. X.fi
  153. X\}
  154. X.SH DATA
  155. X.nf
  156. X4 2 1
  157. X
  158. X1 2  1 1
  159. X3 1 -1 0
  160. X0 1  1 1
  161. X
  162. X5 8 1
  163. X6 1 -1 -1
  164. X.fi
  165. X.SH CAVEATS
  166. XInput can have any amount of white space and integer or floating
  167. Xpoint format. No missing values, however. Also, all equality
  168. Xconstraints are to be specified after the inequality constraints.
  169. X.SH REFERENCE
  170. XRudolfo C. Salazar and Subrata K. Sen,
  171. X``MINIT (MINimum ITerations) algorithm for Linear Programming,''
  172. X\fICollected Algorithms from CACM,\fP
  173. Xalgorithm #333, 1968
  174. X.SH AUTHOR
  175. XTranslated into C from Algol 60 by Badri Lokanathan,
  176. XDept. of EE, University of Rochester
  177. *-*-END-of-minit.1-*-*
  178. echo x - minit.c
  179. sed 's/^X//' >minit.c <<'*-*-END-of-minit.c-*-*'
  180. X/****************************** MINIT ******************************************
  181. X * This file contains procedures to solve a Linear Programming
  182. X * problem of n variables and m constraints, the last p of which
  183. X * are equality constraints by the dual simplex method.
  184. X *
  185. X * The code was originally in Algol 60 and was published in Collected
  186. X * Algorithms from CACM (alg #333) by Rudolfo C. Salazar and Subrata
  187. X * K. Sen in 1968 under the title MINIT (MINimum ITerations) algorithm
  188. X * for Linear Programming.
  189. X * It was directly translated into C by Badri Lokanathan, Dept. of EE,
  190. X * University of Rochester, with no modification to code structure. 
  191. X *
  192. X * The problem statement is
  193. X * Maximise z = cX
  194. X *
  195. X * subject to
  196. X * AX <= b
  197. X * X >=0
  198. X *
  199. X * c is a (1*n) row vector
  200. X * A is a (m*n) matrix
  201. X * b is a (m*1) column vector.
  202. X * e is a matrix with with (m+1) rows and lcol columns (lcol = m+n-p+1)
  203. X *   and forms the initial tableau of the algorithm.
  204. X * td is read into the procedure and should be a very small number,
  205. X *   say 10**-8
  206. X * 
  207. X * The condition of optimality is the non-negativity of
  208. X * e[1,j] for j = 1 ... lcol-1 and of e[1,lcol] = 2 ... m+1.
  209. X * If the e[i,j] values are greater than or equal to -td they are
  210. X * considered to be non-negative. The value of td should reflect the 
  211. X * magnitude of the co-efficient matrix.
  212. X *
  213. X ******************************************************************************/
  214. X
  215. X/***************************** INCLUDES ***************************************/
  216. X#include <stdio.h>
  217. X/************************ CONSTANT DEFINITIONS ********************************/
  218. X#ifndef LARGENUMBER
  219. X#define LARGENUMBER 1e6
  220. X#endif  LARGENUMBER
  221. X#ifndef VLARGENUMBER
  222. X#define VLARGENUMBER 1e8
  223. X#endif  VLARGENUMBER
  224. X#ifndef VSMALLNUMBER
  225. X#define VSMALLNUMBER 1e-8
  226. X#endif  VSMALLNUMBER
  227. X/************************** MACRO DEFINITIONS  ********************************/
  228. X#define ABS(A) (A > 0 ? A: -A)
  229. X#define MAX(A,B) (A > B ? A : B)
  230. X#define MIN(A,B) (A < B ? A : B)
  231. X/************************ FILE-LIMITED VARIABLES ******************************/
  232. Xstatic int k, m, n, p, lcol, L, im, jmin, jm, imax, debug;
  233. Xstatic float td=VSMALLNUMBER;    /* This is application specific. */
  234. Xstatic float gmin, phimax;
  235. X/************************** FILE-LIMITED ARRAYS *******************************/
  236. Xstatic int *imin, *jmax, *ind, *ind1, *chk;
  237. Xstatic float **e, *thmin, *delmax;
  238. X
  239. X/********************************* ZX3LP ***************************************
  240. X * This is a user-specific front end to minit.
  241. X * In its present form, it has been written for compatibility with ifplan. 
  242. X * Note that zx3lp was originally a fortran subroutine. The weird return
  243. X * values and flags (such as IER) are inherited from there.
  244. X * Variable IA and arrays RW, IW are not necessary.
  245. X ******************************************************************************/
  246. Xzx3lp(A,IA,B,C,N,M1,M2,S,PSOL,DSOL,RW,IW,IER)
  247. Xfloat **A, *B, *C, *PSOL, *DSOL, *RW, *S;
  248. Xint *IA, *N, *M1, *M2, *IW, *IER;
  249. X{
  250. X    int err;
  251. X
  252. X    /* Allocate space for arrays and initialize globals. */
  253. X    if(!minit_space_handler(*N,*M1+*M2,*M2))
  254. X    {
  255. X        (void) fprintf(stderr,"Space problems in LP handler.\n");
  256. X        return;
  257. X    }
  258. X
  259. X    /* Invoke minit here. */
  260. X    err = minit(A,B,C,PSOL,DSOL,S);
  261. X    switch(err)
  262. X    {
  263. X        case 1:
  264. X        case 2:
  265. X        *IER = 133;
  266. X        break;
  267. X
  268. X        case 3:
  269. X        *IER = 131;
  270. X        break;
  271. X
  272. X        default:
  273. X        *IER = 0;
  274. X    }
  275. X}
  276. X
  277. X/************************ minit_space_handler **********************************
  278. X * This routine performs space maintenance and initializes global arrays.     
  279. X * It looks at n, m and p, which are static in this file, to look for
  280. X * previously allocated space.
  281. X ******************************************************************************/
  282. Xint
  283. Xminit_space_handler(N,M,P)
  284. Xint N, M, P;
  285. X{
  286. X    register int i, j;
  287. X    float **tmp;
  288. X    static int MS, LS;        /* To keep track of array sizes. */
  289. X    char *calloc(), *malloc(), *realloc();
  290. X
  291. X    /* Initialize globals. */
  292. X    m = M;
  293. X    n = N;
  294. X    p = P;
  295. X    lcol = m + n - p + 1;
  296. X
  297. X    if(LS == 0)
  298. X    {
  299. X        /* First pass. Allocate space for every array. */
  300. X
  301. X        MS = m + 1;
  302. X        LS = m + n - p + 1;
  303. X        if(!(jmax = (int *) calloc((unsigned) MS,sizeof(int))))
  304. X            return(0);
  305. X
  306. X        if(!(ind1 = (int *) calloc((unsigned) MS,sizeof(int))))
  307. X            return(0);
  308. X
  309. X        if(!(chk = (int *) calloc((unsigned) MS,sizeof(int))))
  310. X            return(0);
  311. X
  312. X        if(!(delmax = (float *) calloc((unsigned) MS,sizeof(float))))
  313. X            return(0);
  314. X
  315. X        if(!(imin = (int *) calloc((unsigned) LS,sizeof(int))))
  316. X            return(0);
  317. X
  318. X        if(!(ind = (int *) calloc((unsigned) LS,sizeof(int))))
  319. X            return(0);
  320. X
  321. X        if(!(thmin = (float *) calloc((unsigned) LS,sizeof(float))))
  322. X            return(0);
  323. X
  324. X        if(!(tmp=e=(float **) calloc((unsigned) MS,sizeof(float *))))
  325. X            return(0);
  326. X
  327. X        for(i = 0; i < MS; i++)
  328. X            if(!(*(tmp++)=(float *) calloc((unsigned) LS,
  329. X                    sizeof(float))))
  330. X                return(0);
  331. X
  332. X        return(1);
  333. X    }
  334. X
  335. X    if(M + 1 > MS)
  336. X    {
  337. X        /* Need to reallocate space. */
  338. X        MS = M + 1;
  339. X        if(!(jmax = (int *) realloc((char *)jmax,
  340. X                (unsigned)(MS*sizeof(int)))))
  341. X            return(0);
  342. X
  343. X        if(!(ind1 = (int *) realloc((char *) ind1,
  344. X                (unsigned)(MS*sizeof(int)))))
  345. X            return(0);
  346. X
  347. X        if(!(chk = (int *) realloc((char *) chk,
  348. X                (unsigned)(MS*sizeof(int)))))
  349. X            return(0);
  350. X
  351. X        if(!(delmax = (float *) realloc((char *) delmax,
  352. X                (unsigned)(MS*sizeof(float)))))
  353. X            return(0);
  354. X
  355. X        if(!(e=(float **) realloc((char *) e,
  356. X                (unsigned)(MS*sizeof(float *)))))
  357. X            return(0);
  358. X
  359. X        for(tmp = e + m, i = 0; i < MS; i++)
  360. X            if(!(*(tmp++)=(float *)
  361. X                    malloc((unsigned)(LS*sizeof(float)))))
  362. X                return(0);
  363. X    }
  364. X
  365. X    if(lcol > LS)
  366. X    {
  367. X        LS = lcol;
  368. X        if(!(ind = (int *) realloc((char *) ind,
  369. X                (unsigned)(LS*sizeof(int)))))
  370. X            return(0);
  371. X
  372. X        if(!(imin = (int *) realloc((char *) imin,
  373. X                (unsigned)(LS*sizeof(int)))))
  374. X            return(0);
  375. X
  376. X        if(!(thmin = (float *) realloc((char *) thmin,
  377. X                (unsigned)(LS*sizeof(float)))))
  378. X            return(0);
  379. X
  380. X        for(tmp = e, i = 0; i < MS; tmp++, i++)
  381. X            if(!(*tmp=(float *) realloc((char *) tmp,
  382. X                    (unsigned)(LS*sizeof(float)))))
  383. X                return(0);
  384. X    }
  385. X
  386. X    /* Finally, initialize all arrays to 0. */
  387. X    for(i = 0; i <= m; i++)
  388. X    {
  389. X        jmax[i] = ind1[i] = chk[i] = 0;
  390. X        delmax[i] = 0.0;
  391. X        for(j = 0; j < lcol; j++)
  392. X            e[i][j] = 0.0;
  393. X    }
  394. X
  395. X    for(j = 0; j < lcol; j++)
  396. X    {
  397. X        imin[j] = ind[j] = 0;
  398. X        thmin[j] = 0.0;
  399. X    }
  400. X
  401. X    return(1);
  402. X}
  403. X
  404. X/********************************* MINIT ***************************************
  405. X * This is the main procedure. It is invoked with the various matrices,
  406. X * after space for other arrays has been generated elsewhere (in zx3lp.)
  407. X * It returns
  408. X * 0 if everything went OK and x, w, z as the solutions.
  409. X * 1 if no solution existed.
  410. X * 2 if primal had no feasible solutions.
  411. X * 3 if primal had unbounded solutions.
  412. X ******************************************************************************/
  413. Xint
  414. Xminit(A,b,c,x,w,z)
  415. Xfloat **A, *b, *c, *x, *w, *z;
  416. X{
  417. X    register int i, j;
  418. X    void tab();
  419. X
  420. X    /* Generate initial tableau. */
  421. X    for(j = 0; j < n; j++)
  422. X        e[0][j] = -c[j];
  423. X
  424. X    for(i = 0; i < m; i++)
  425. X    {
  426. X        for(j = 0; j < n; j++)
  427. X            e[i+1][j] = A[i][j];
  428. X    }
  429. X
  430. X    for(j = 0; j < m; j++)
  431. X        e[j+1][lcol-1] = b[j];
  432. X
  433. X    for(i = 0; i < m - p; i++)
  434. X        e[1+i][n+i] = 1.0;
  435. X
  436. X    /* Now begins the actual algorithm. */
  437. X    for(i = 1; i < m+1; i++)
  438. X        chk[i] = -1;    /* Indexing problem; Algol
  439. X                 * version treates 0 as out
  440. X                 * of bounds, in C we prefer -1.
  441. X                 */
  442. X
  443. X    if(!p)    /* There are no equality constraints */
  444. X        goto RCS;
  445. X    else
  446. X    {
  447. X    if(phase1())
  448. X        return(1);
  449. X    }
  450. X        
  451. X    RCS: L = 1; k = 1;
  452. X
  453. X    if(debug)
  454. X        tab();    /* Print the tableau. */
  455. X
  456. X    for(j = 0; j < lcol - 1; j++)
  457. X    {
  458. X        if(e[0][j] < -td)
  459. X            ind[(L++)-1] = j; /* ind[L] keeps track of the
  460. X                       * columns in which e[0][j]
  461. X                       * is negative.
  462. X                       */
  463. X    }
  464. X
  465. X    for(i = 1; i < m + 1; i++)
  466. X    {
  467. X        if(e[i][lcol-1] < -td)
  468. X            ind1[(k++)-1] = i; /* ind1[k] keeps track of the
  469. X                        * rows in which e[i][lcol]
  470. X                        * is negative.
  471. X                        */
  472. X    }
  473. X
  474. X    if(L == 1)
  475. X    {
  476. X        if(k == 1) /* Results */
  477. X            goto RESULTS;
  478. X        else
  479. X        {
  480. X            if(k == 2)
  481. X            {
  482. X                for(j = 0; j < lcol - 1; j++)
  483. X                {
  484. X                    if(e[ind1[0]][j] < 0)
  485. X                        goto R;
  486. X                }
  487. X                /* Primal problem has no feasible solutions. */
  488. X                return(2);
  489. X            }
  490. X            else
  491. X                goto R;
  492. X        }
  493. X    }
  494. X    else
  495. X    {
  496. X        if(L == 2)
  497. X        {
  498. X            if(k == 1)
  499. X            {
  500. X                for(i = 1; i < m + 1; i++)
  501. X                {
  502. X                    if(e[i][ind[0]] > 0)
  503. X                        goto C;
  504. X                }
  505. X
  506. X                /* Primal problem is unbounded. */
  507. X                return(3);
  508. X            }
  509. X            else
  510. X                goto S;
  511. X        }
  512. X
  513. X        if(k == 1)
  514. X            goto C;
  515. X        else
  516. X            goto S;
  517. X    }
  518. X
  519. X    R:
  520. X    prophi();
  521. X    if(rowtrans(imax,jm))
  522. X        return(1);
  523. X    goto RCS;
  524. X
  525. X    C:
  526. X    progamma();
  527. X    if(rowtrans(im,jmin))
  528. X        return(1);
  529. X    goto RCS;
  530. X
  531. X    S:
  532. X    progamma();
  533. X    prophi();
  534. X    if(gmin == LARGENUMBER)
  535. X    {
  536. X        if(rowtrans(imax,jm))
  537. X            return(1);
  538. X        goto RCS;
  539. X    }
  540. X
  541. X    if(phimax == - LARGENUMBER)
  542. X    {
  543. X        if(rowtrans(im,jmin))
  544. X            return(1);
  545. X        goto RCS;
  546. X    }
  547. X
  548. X    if(ABS(phimax) > ABS(gmin))
  549. X    {
  550. X        if(rowtrans(imax,jm))
  551. X            return(1);
  552. X    }
  553. X    else
  554. X    {
  555. X        if(rowtrans(im,jmin))
  556. X            return(1);
  557. X    }
  558. X    goto RCS;
  559. X
  560. X    RESULTS:
  561. X    /* Output results here. */
  562. X    *z = e[0][lcol-1];
  563. X    for(i = 0; i < n; i++)
  564. X        x[i] = 0.0;
  565. X
  566. X    for(j = 0; j < m; j++)
  567. X        x[j] = 0.0;
  568. X
  569. X    for(i = 1; i < m + 1; i++)
  570. X    {
  571. X        if(chk[i] >= n)
  572. X            chk[i] = -1;
  573. X
  574. X        if(chk[i] > -1)
  575. X            x[chk[i]] = e[i][lcol-1];
  576. X    }
  577. X
  578. X    for(j = n; j < lcol - 1; j++)
  579. X        w[j-n] = e[0][j];
  580. X    
  581. X    return(0);
  582. X}
  583. X
  584. X/****************************** rowtrans ***************************************
  585. X * Performs the usual tableau transformations in a linear programming
  586. X * problem, (p,q) being the pivotal element.
  587. X * Returns the following error codes:
  588. X * 0: Everything was OK.
  589. X * 1: No solution.
  590. X ******************************************************************************/
  591. Xint
  592. Xrowtrans(p,q)
  593. Xint p, q;
  594. X{
  595. X    register int i, j;
  596. X    float dummy;
  597. X
  598. X    if(p == -1 || q == -1) /* No solution. */
  599. X        return(1);
  600. X
  601. X    dummy = e[p][q];
  602. X
  603. X    if(debug)
  604. X        (void) printf("--\nPivot element is e[%d][%d] = %f\n",p,q,dummy);
  605. X
  606. X    for(j = 0; j < lcol; j++)
  607. X        e[p][j] /= dummy; 
  608. X
  609. X    for(i = 0; i < m + 1; i++)
  610. X    {
  611. X        if(i != p)
  612. X        {
  613. X            if(e[i][q] != 0.0)
  614. X            {
  615. X                dummy = e[i][q];
  616. X                for(j = 0; j < lcol; j++)
  617. X                    e[i][j] -= e[p][j] * dummy;
  618. X            }
  619. X        }
  620. X    }
  621. X
  622. X    chk[p] = q;
  623. X    return(0);
  624. X} /* rowtrans */
  625. X
  626. X/****************************** progamma ***************************************
  627. X * Performs calculations over columns to determine the pivot element.
  628. X ******************************************************************************/
  629. Xprogamma()
  630. X{
  631. X    float theta, gamma;
  632. X    register int i, L1;
  633. X
  634. X    gmin = LARGENUMBER;    /* gmin is set to a large no. for
  635. X                 * initialization purposes.
  636. X                 */
  637. X    jmin = -1;        /* Array indices in C start from 0 */
  638. X
  639. X    for(L1 = 0; L1 < L - 1; L1++)
  640. X    {
  641. X        imin[ind[L1]] = 0;
  642. X        thmin[ind[L1]] = LARGENUMBER;
  643. X        for(i = 1; i < m + 1; i++)
  644. X        {
  645. X            if(e[i][ind[L1]] > td && e[i][lcol-1] >= -td)
  646. X            {
  647. X                theta = e[i][lcol-1] / e[i][ind[L1]];
  648. X                if(theta < thmin[ind[L1]])
  649. X                {
  650. X                    thmin[ind[L1]] = theta;
  651. X                    imin[ind[L1]] = i;
  652. X                }
  653. X            }
  654. X        }
  655. X
  656. X        if(thmin[ind[L1]] == LARGENUMBER)
  657. X            gamma = VLARGENUMBER;
  658. X        else
  659. X            gamma = thmin[ind[L1]] * e[0][ind[L1]];
  660. X
  661. X        if(gamma < gmin)
  662. X        {
  663. X            gmin = gamma;
  664. X            jmin = ind[L1];
  665. X        }
  666. X    }
  667. X    if(jmin > -1)
  668. X        im = imin[jmin];
  669. X} /* progamma */
  670. X
  671. X/****************************** prophi *****************************************
  672. X * Performs calculations over rows to determine the pivot element.
  673. X ******************************************************************************/
  674. Xprophi()
  675. X{
  676. X    float delta, phi;
  677. X    register int j, k1;
  678. X
  679. X    phimax = - LARGENUMBER;    /* phimax is set to a small no. for
  680. X                 * initialization purposes.
  681. X                 */
  682. X    imax = -1;        /* Array indices in C start from 0 */
  683. X    
  684. X    for(k1 = 0; k1 < k - 1; k1++)
  685. X    {
  686. X        jmax[ind1[k1]] = 0;
  687. X        delmax[ind1[k1]] = - LARGENUMBER;
  688. X        for(j = 0; j < lcol - 1; j++)
  689. X        {
  690. X            if(e[ind1[k1]][j] < -td && e[0][j] >= -td)
  691. X            {
  692. X                delta = e[0][j] / e[ind1[k1]][j];
  693. X                if(delta > delmax[ind1[k1]])
  694. X                {
  695. X                    delmax[ind1[k1]] = delta;
  696. X                    jmax[ind1[k1]] = j;
  697. X                }
  698. X            }
  699. X        }
  700. X
  701. X        if(delmax[ind1[k1]] == - LARGENUMBER)
  702. X            phi = - VLARGENUMBER;
  703. X        else
  704. X            phi = delmax[ind1[k1]] * e[ind1[k1]][lcol-1];
  705. X        
  706. X        if(phi > phimax)
  707. X        {
  708. X            phimax = phi;
  709. X            imax = ind1[k1];
  710. X        }
  711. X    }
  712. X    if(imax > -1)
  713. X        jm = jmax[imax];
  714. X} /* prophi */
  715. X
  716. X/****************************** phase1 *****************************************
  717. X * Applied only to equality constraints if any.
  718. X ******************************************************************************/
  719. Xphase1()
  720. X{
  721. X    float theta, gamma;
  722. X    register int i, j, r;
  723. X    /* Fix suggested by Holmgren, Obradovic, Kolm. */
  724. X    register int im1, jmin1, first;
  725. X    void tab();
  726. X
  727. X    im1 = jmin1 = -1;
  728. X    /* Fix suggested by Messham to allow negative coeffs. in
  729. X     * equality constraints.
  730. X     */
  731. X    for(i = m - p + 1; i < m + 1; i++)
  732. X    {
  733. X        if(e[i][lcol - 1] < 0)
  734. X        {
  735. X            for(j = 0; j < lcol; j++)
  736. X                e[i][j] = -e[i][j];
  737. X        }
  738. X    }
  739. X
  740. X    for(r = 0; r < p; r++)
  741. X    {
  742. X        gmin = LARGENUMBER;    /* gmin is set to a large no. for
  743. X                     * initialization purposes.
  744. X                     */
  745. X        L = 1;
  746. X        jmin = -1;
  747. X        first = 1;
  748. X        for(j = 0; j < n; j++)
  749. X        {
  750. X            thmin[j] = LARGENUMBER;
  751. X            /* Fix suggested by Kolm and Dahlstrand */
  752. X            /* if(e[0,j] < 0) */
  753. X            if(e[0][j] < -td)
  754. X                ind[(L++)-1] = j;
  755. X        }
  756. X
  757. X    L1:    if(L == 1)
  758. X        {
  759. X            for(j = 0; j < n; j++)
  760. X                ind[j] = j;
  761. X
  762. X            L = n + 1;
  763. X        }
  764. X
  765. X        for(k = 0; k < L - 1; k++)
  766. X        {
  767. X            for(i = m - p + 1; i < m + 1; i++)
  768. X                if(chk[i] == -1)
  769. X                {
  770. X                    /* Fix suggested by Kolm
  771. X                     * and Dahlstrand
  772. X                     */
  773. X                    /* if(e[i][ind[k]] > 0.0) */
  774. X                    if(e[i][ind[k]] > td)
  775. X                    {
  776. X                        if((theta = e[i][lcol-1] /
  777. X                          e[i][ind[k]]) < thmin[ind[k]])
  778. X                        {
  779. X                            thmin[ind[k]] = theta;
  780. X                            imin[ind[k]] = i;
  781. X                        }
  782. X                    }
  783. X                }
  784. X
  785. X            /* Fix suggested by Obradovic overrides
  786. X             * fixes suggested by Kolm and Dahstrand
  787. X             * as well as Messham.
  788. X             */
  789. X            if(thmin[ind[k]] < LARGENUMBER)
  790. X            {
  791. X                gamma = thmin[ind[k]] * e[0][ind[k]];
  792. X                if(gamma < gmin)
  793. X                {
  794. X                    gmin = gamma;
  795. X                    jmin = ind[k];
  796. X                }
  797. X            }
  798. X        }
  799. X        if(jmin == -1)
  800. X        {
  801. X            if(first)
  802. X            {
  803. X                first = 0;
  804. X                L = 1;
  805. X                goto L1;
  806. X            }
  807. X            else
  808. X                im = -1;
  809. X        }
  810. X        else
  811. X            im = imin[jmin];
  812. X
  813. X        if(im == im1 && jmin == jmin1)
  814. X        {
  815. X            L = 1;
  816. X            goto L1;
  817. X        }
  818. X
  819. X        if(debug)
  820. X            tab();    /* Print the tableau. */
  821. X
  822. X        if(rowtrans(im,jmin))
  823. X            return(1);
  824. X        
  825. X        im1 = im;
  826. X        jmin1 = jmin;
  827. X    }
  828. X    return(0);
  829. X} /* phase1 */
  830. X
  831. X/****************************** tab *****************************************
  832. X * The following procedure is for debugging. It simply prints the
  833. X * current tableau.
  834. X ******************************************************************************/
  835. Xstatic void
  836. Xtab()
  837. X{
  838. X    register int i, j;
  839. X
  840. X    (void) printf("\n");
  841. X
  842. X    for(i = 0; i < 35; i++)
  843. X        (void) printf("-");
  844. X
  845. X    (void) printf(" TABLEAU ");
  846. X
  847. X    for(i = 0; i < 35; i++)
  848. X        (void) printf("-");
  849. X
  850. X    (void) printf("\n");
  851. X
  852. X    for(i = 0; i < m+1; i++)
  853. X    {
  854. X        for(j = 0; j < lcol; j++)
  855. X            (void) printf("%6.3f ",e[i][j]);
  856. X
  857. X        (void) printf("\n");
  858. X    }
  859. X}
  860. *-*-END-of-minit.c-*-*
  861. echo x - minmain.c
  862. sed 's/^X//' >minmain.c <<'*-*-END-of-minmain.c-*-*'
  863. X/*
  864. X * This is a front end to test the linear programming package
  865. X * minit. This algorithm was written by Das and Salazar in algol.
  866. X *
  867. X * Solve the LP      T
  868. X *        max C X  subj. to
  869. X *              AX <= B
  870. X *               X >= 0
  871. X */
  872. X
  873. X#include <stdio.h>
  874. X#include <string.h>
  875. Xchar *calloc();
  876. X
  877. Xmain(argc,argv)
  878. Xint argc;
  879. Xchar **argv;
  880. X{
  881. X    int  ier,m,n,m1,m2;    /* Dimensions of various matrices */
  882. X    float **A,**A1,*b,*c,*x,*w,z,tmp;
  883. X    char format[64], *usage, *sprintf();
  884. X    int suppress;
  885. X    int int_part, frac_part;
  886. X    float precision;
  887. X    register int i,j,arg;
  888. X    FILE *fopen(), *in;
  889. X
  890. X    n = m1 = m2 = 0;
  891. X    in = stdin;
  892. X    suppress = 1;    /* Suppress printing interactive messages. */
  893. X    precision = 0.0;
  894. X
  895. X    usage = "\
  896. XUsage:\tminit [-pprec] [-i[filename]]\n\
  897. Xor:\tminit [-pprec] < filename\n\
  898. XFor detailed help: minit -help\n";
  899. X
  900. X    for (arg = 1; arg < argc; arg++)
  901. X    {
  902. X        if (argv[arg][0] != '-' ||
  903. X            (argv[arg][1] != 'p' && argv[arg][1] != 'i'))
  904. X        {
  905. X            if (!strcmp(argv[arg],"-help") || !strcmp(argv[arg],"help"))
  906. X            (void) system("man minit");
  907. X            else
  908. X            (void) fputs(usage, stderr);
  909. X            exit(1);
  910. X        }
  911. X
  912. X        if (argv[arg][1] == 'p')
  913. X            (void) sscanf(&(argv[arg][2]),"%f",&precision);
  914. X        else    /* if argv[arg][1] == 'i') */
  915. X        {
  916. X            if (in != stdin)    /* in already assigned. */
  917. X            {
  918. X                (void) fputs("Only one input file permitted.\n",
  919. X                    stderr);
  920. X                exit(1);
  921. X            }
  922. X            if((in = fopen(&(argv[arg][2]),"r")) == NULL)
  923. X            {
  924. X                (void) fprintf(stderr,
  925. X                    "No input file %s; interactive mode\n",
  926. X                    &(argv[arg][2]));
  927. X
  928. X                in = stdin;
  929. X                suppress = 0;
  930. X            }
  931. X        }
  932. X    }
  933. X
  934. X    if (!suppress)
  935. X        (void) fputs("Enter value of n \(No. of unknowns\): ", stderr);
  936. X
  937. X    (void) fscanf(in,"%d",&n);
  938. X
  939. X    if (!suppress)
  940. X        (void) fputs("Enter no. of inequality constraints: ", stderr);
  941. X
  942. X    (void) fscanf(in,"%d",&m1);
  943. X
  944. X    if (!suppress)
  945. X        (void) fputs("Enter no. of equality constraints: ", stderr);
  946. X
  947. X    (void) fscanf(in,"%d",&m2);
  948. X
  949. X    m = m1+m2;
  950. X
  951. X    /* Allocate space for the arrays */
  952. X        A1 = A     = (float **) calloc((unsigned)m,sizeof(float *));
  953. X    for(i=0;i<m;i++)
  954. X        *(A1++) = (float *) calloc((unsigned)n,sizeof(float));
  955. X
  956. X    b     = (float *) calloc((unsigned)m,sizeof(float));
  957. X    c     = (float *) calloc((unsigned)n,sizeof(float));
  958. X    x     = (float *) calloc((unsigned)n,sizeof(float));
  959. X    w     = (float *) calloc((unsigned)m,sizeof(float));
  960. X
  961. X    if (!suppress)
  962. X        (void) fprintf(stderr,"Enter \(%d by %d\) elements of A:\n",
  963. X            m,n);
  964. X    for(i=0;i<m;i++)
  965. X        for(j=0;j<n;j++)
  966. X        {
  967. X            (void) fscanf(in,"%f",&tmp);
  968. X            A[i][j] = tmp;;
  969. X        }
  970. X
  971. X    if (!suppress)
  972. X        (void) fprintf(stderr,
  973. X            "Enter %d elements of b, entered as a linear array:\n ",
  974. X                m);
  975. X    for(i=0;i<m;i++)
  976. X    {
  977. X        (void) fscanf(in,"%f",&tmp);
  978. X        b[i] = tmp;
  979. X    }
  980. X
  981. X    if (!suppress)
  982. X        (void) fprintf(stderr,
  983. X            "Enter %d elements of c, entered as a linear array:\n",
  984. X                n);
  985. X    for(j=0;j<n;j++)
  986. X    {
  987. X        (void) fscanf(in,"%f",&tmp);
  988. X        c[j] = tmp;
  989. X    }
  990. X
  991. X    if (suppress)
  992. X    {
  993. X        (void) fputs("INPUT DATA:\n",stderr);
  994. X        (void) fprintf(stderr,"No. of variables \(n\) = %d\n", n);
  995. X        (void) fprintf(stderr,
  996. X            "No. of inequality constraints \(m1\) = %d\n", m1);
  997. X        (void) fprintf(stderr,
  998. X            "No. of equality constraints \(m2\) = %d\n", m2);
  999. X    }
  1000. X
  1001. X    (void) fputs("------------------------------",stderr);
  1002. X    (void) fputs(" EXECUTING MINIT ",stderr);
  1003. X    (void) fputs("------------------------------",stderr);
  1004. X    (void) fputc('\n',stderr);
  1005. X
  1006. X    zx3lp(A,(int *)NULL,b,c,&n,&m1,&m2,&z,x,w,(float *)NULL,
  1007. X        (int *)NULL,&ier);
  1008. X    switch(ier)
  1009. X    {
  1010. X        case 133:
  1011. X        break;
  1012. X
  1013. X        case 1:
  1014. X        (void) fprintf(stderr,"No solution.\n");
  1015. X        exit(1);
  1016. X
  1017. X        case 131:
  1018. X        (void) fprintf(stderr,"Primal has unbounded solution.\n");
  1019. X        exit(3);
  1020. X    }
  1021. X
  1022. X    /* Make sure precision is acceptible. */
  1023. X    int_part = precision;
  1024. X    frac_part = precision - int_part;
  1025. X    if (int_part <= frac_part || int_part > 25)
  1026. X        precision = 10.3;    /* The default precision. */
  1027. X
  1028. X    (void) sprintf(format,"\nValue of z: %%%gg\n",precision);
  1029. X    (void) printf(format,z);
  1030. X    (void) puts("Primal solution:");
  1031. X
  1032. X    (void) sprintf(format,"%%%gg ",precision);
  1033. X    for(j=0;j<n;j++)
  1034. X        (void) printf(format,x[j]);
  1035. X
  1036. X    (void) puts("\nDual solution:");
  1037. X    for(i=0;i<m;i++)
  1038. X        (void) printf(format,w[i]);
  1039. X
  1040. X    (void) putchar('\n');
  1041. X    exit(0);
  1042. X}
  1043. *-*-END-of-minmain.c-*-*
  1044. echo x - example
  1045. sed 's/^X//' >example <<'*-*-END-of-example-*-*'
  1046. X4 2 1
  1047. X
  1048. X1 2  1 1
  1049. X3 1 -1 0
  1050. X0 1  1 1
  1051. X
  1052. X5 8 1
  1053. X6 1 -1 -1
  1054. *-*-END-of-example-*-*
  1055. exit
  1056.  
  1057.  
  1058.