home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / adaptor.zip / adapt.zip / adaptor / examples / hpf_gen / simplex / simplex.f < prev    next >
Text File  |  1993-06-25  |  9KB  |  388 lines

  1.       program cm_fullsimplex
  2.  
  3.       include 'simplex.h'
  4.       logical phaseII
  5.  
  6.       real*8 a_out
  7. c
  8. c********************************************************************
  9. c
  10. c   written by Yong Li, SCCS/NPAC at Syracuse University
  11. c   version date: 9/29/1991
  12. c
  13. c   The simplex method for solving linear programming problems.
  14. c   There is a data header file called simplex.h
  15. c
  16. c*******************************************************************
  17. c
  18.  
  19.       phaseII = .true.
  20.       print *, ' '
  21.       print *, ' FULL SIMPLEX METHOD FOR LINEAR PROGRAMMING '
  22.       print *, '      ON THE CONNECTION MACHINE'
  23.       print *, ' '
  24.  
  25.       call initial (a, nonbasic)
  26. c
  27. c  set cm timer
  28. c
  29.       call cm_timer_clear(0)
  30.       call cm_timer_start(0)
  31.  
  32.       if (numGE .EQ. 0) then
  33.         print *, ' There is no phase I'
  34.        else
  35.         print *, ' Phase I is working...'
  36.         call simplex (1, a, nonbasic)
  37.         print *, ' Phase I takes', iteration, ' iterations'
  38.         a_out = a(mm,nn)
  39.         if ((DABS(a_out) .GT. small) .OR. cont) then
  40.           phaseII = .false.
  41.           print *, ' Phase I not successful'
  42.           print *, ' Sum of the artifical variables is ', a_out
  43.          else
  44.           print *, ' Phase I successful'
  45.         end if
  46.       end if
  47.       if (phaseII) then
  48.         print *, ' Phase II is working...'
  49.         call simplex (2, a, nonbasic)
  50. c
  51. c  stop timer
  52. c
  53.         call cm_timer_stop(0)
  54.  
  55.         print *, ' Phase II takes  ', iteration, ' iterations'
  56.         if (bounded) then
  57.           print *, ' Phase II successful '
  58.           a_out = a(m1, nn)
  59.           print *, ' Minmum is Z = ', -a_out
  60.          else
  61.           print *, ' Variable ', s, ' is unbounded'
  62.         end if
  63.         call cm_timer_print(0)
  64.       end if
  65.  
  66.  
  67.       end
  68.  
  69.       subroutine initial (a, nonbasic)
  70.  
  71.       include 'simplex.h'
  72.       integer i, j, k
  73.       real*8 asum
  74.  
  75. c
  76. c  get data
  77. c
  78.       print *, ' '
  79.       call getdata (a, nonbasic)
  80.       print *, ' '
  81.       print *, m, ' constrants'
  82.       print *, n, ' variables'
  83.       print *, ' constrants (G  E  L) = (', numG, numE, numL, ' )'
  84.       print *, ' '
  85.  
  86.       FORALL (i=1:mm, j=n+1:nn-1) a(i, j) = zero
  87.       FORALL (i=n+1:n+numG) a(i-n,i) = -one      
  88.       FORALL (i=n+numG+1:n+numG+numL) a(numGE+i-n-numG, i) = one
  89.       FORALL (i=n2+1:n2+numGE) a(i-n2, i) = one
  90.       FORALL (j=1:numGE) basic(j) = n2 + j
  91.       FORALL (j=1:numL) basic(numGE+j) = n + numG + j
  92.       nonbasic(1:n1) = .true.
  93.       do j = 1, m
  94.          nonbasic(basic(j)) = .false.
  95.       end do
  96.  
  97. c     FORALL (j=1:n2) a(mm, j) = -SUM(a(1:numGE, j))
  98. !hpf$ independent, local_access
  99.       do j = 1, n2 
  100.          a(mm,j) = 0
  101.          do k = 1, numGE
  102.             a(mm,j) = a(mm,j) - a(k,j)
  103.          end do
  104.       end do
  105.  
  106.       asum = -SUM(a(1:numGE, nn))
  107.       a(mm, nn) = asum
  108.       iteration = 0
  109.  
  110.       end
  111.  
  112.       subroutine simplex (phase, a, nonbasic)
  113.  
  114.       include 'simplex.h'
  115.       integer phase
  116.  
  117.       if (phase .EQ. 1) then
  118.         rindex = mm
  119.         cindex = n1
  120.        else
  121.         rindex = m1
  122.         cindex = n2
  123.       end if
  124.  
  125.       call next (a, nonbasic)
  126.       do while (cont .AND. bounded)
  127.         call next (a, nonbasic)
  128.       end do
  129.  
  130.       end
  131.  
  132.       subroutine next (a, nonbasic)
  133.  
  134.       include 'simplex.h'
  135.       real*8 pivot, tmp
  136.       integer iloc, jloc, k, k1
  137.       real*8 mina
  138.       real*8 repa (m)
  139. cmf$  layout repa (:replicated)
  140.  
  141. c     jloc = MINLOC(a(rindex, 1:cindex), nonbasic(1:cindex))
  142.       jloc = 1
  143.       mina = 100000.0
  144. !hpf$ independent, local_access
  145.       do k = 1, cindex 
  146.          if (nonbasic(k)) then
  147.             reduce (minval, mina, a(rindex,k), jloc, k)
  148.          end if
  149.       end do
  150.  
  151.       s = jloc
  152.       cont = (mina .LT. -small)
  153.       if (cont) then
  154.         bounded = ANY(a(1:m, s) .GT. small)
  155.         if (bounded) then
  156. c         iloc = MINLOC(a(1:m, nn)/a(1:m, s), a(1:m, s) .GT. small)
  157.           iloc = 1
  158.           mina = 100000.0
  159.           repa (1:m) = a(1:m,s)
  160. !hpf$ independent, local_access
  161.           do k = 1, m 
  162.              if (repa(k) .GT. small) then
  163.                 reduce (minval, mina, a(k,nn)/repa(k), iloc, k)
  164.              end if
  165.           end do
  166.           r = iloc
  167.           nonbasic(basic(r)) = .true.
  168.           basic(r) = s
  169.           nonbasic(s) = .false.
  170. c
  171. c  update the solution
  172. c
  173.           pivot = a(r, s)
  174.           tmp = a(r, nn)/pivot
  175.           a(:, nn) = a(:, nn) - tmp*a(:, s)
  176.           a(r, nn) = tmp
  177.           a(r, 1:cindex) = a(r, 1:cindex)/pivot
  178.           row(1:cindex) = a(r, 1:cindex)
  179.           forall (k=1:cindex,k1=1:mm)
  180.             tmpA (k1,k) = a(k1,s) * a(r,k)
  181.           end forall
  182. c         tmpA = SPREAD(a(:, s), 2, cindex) *
  183. c    &           SPREAD(a(r, 1:cindex), 1, mm)
  184.           a(:, 1:cindex) = a(:, 1:cindex) - tmpA(:, 1:cindex)
  185.           a(r, 1:cindex) = row(1:cindex)
  186.           iteration = iteration + 1
  187.         end if
  188.       end if
  189.  
  190.       end
  191.  
  192. C
  193. C  Version Dated:  January 24, 1991
  194. CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  195. C            GetData                    C
  196. CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  197.  
  198.     subroutine GetData (a, nonbasic)
  199.  
  200.         include 'simplex.h'
  201.         integer i, j, k, ii
  202.     integer numRow, colCount
  203.     character*8 rowLab(d3)
  204.     integer SearchRow, count
  205.     character*4 tmpConstant
  206.     character*8 nameStr, tmp1Lab, tmp3Lab, tmp4Lab, tmpLab
  207.     character*1 rowType(d3)
  208.     real*8 tmp1Data, tmp2Data
  209.     
  210.     READ(*,'(A4,T15,A8)') tmpConstant, nameStr
  211.     if (tmpConstant .NE. 'NAME') then
  212.         print *, 'Input format error, missing name field'
  213.         stop
  214.     endif
  215.         print *, ' The test data file is ', nameStr
  216.     READ(*,'(A4)') tmpConstant
  217.     if (tmpConstant .NE. 'ROWS') then
  218.         print *, 'Input format error, missing ROWS field'
  219.         stop
  220.     endif
  221.     do i = 1, d1 
  222.         READ(*,'(A4,T2,A1,T5,A8)') tmpConstant, rowType(i), rowLab(i)
  223.         if (tmpConstant .EQ. 'COLU') then
  224.         numRow = i - 1
  225.             goto 10
  226.         endif
  227.     end do
  228.     if (tmpConstant .NE. 'COLU') then
  229.         print *, 'Error: too many rows'
  230.         stop
  231.     endif
  232. 10      continue
  233. C
  234. C  Looking for the row with row type N, and exchange it with the last row
  235. C
  236.         do i = 1, numRow
  237.            if (rowType(i) .EQ. 'N') then
  238.               call Exchange(rowType, rowLab, i, numRow)
  239.               goto 20
  240.            end if
  241.         end do
  242. 20      continue
  243. C
  244. C  Rearrange the rows according to the order of row type G, E, L
  245. C
  246.     i = 1
  247.     j = numRow-1
  248.     do ii = 1, numRow-1
  249.        do k = i, numRow-1
  250.           if (rowType(k) .NE. 'G') then
  251.              i = k
  252.                  goto 30
  253.           endif
  254.        end do
  255. 30        continue
  256.       do k = j, 1, -1
  257.          if (rowType(k) .EQ. 'G') then
  258.         j = k
  259.         goto 40
  260.          endif
  261.       end do
  262. 40        continue
  263.       if (i .GT. j) then
  264.              goto 50
  265.       else 
  266.          call Exchange(rowType,rowLab,i,j)
  267.       endif
  268.     end do
  269. 50      continue
  270.  
  271.     i = 1
  272.     j = numRow-1
  273.     do ii = 1, numRow-1
  274.       do k = i, numRow-1
  275.          if ((rowType(k) .NE. 'E') .AND. (rowType(k) .NE. 'G')) then
  276.         i = k
  277.         goto 60
  278.          endif
  279.       end do
  280. 60        continue
  281.       do k = j, 1, -1
  282.          if (rowType(k) .NE. 'L') then
  283.         j = k
  284.         goto 70
  285.          endif
  286.       end do
  287. 70        continue
  288.       if (i .GT. j) then
  289.              goto 80
  290.       else 
  291.          call Exchange(rowType,rowLab,i,j)
  292.       endif
  293.     end do
  294. 80      continue
  295. c
  296.         a(1:numRow+1, 1:nn) = 0.0
  297.         Count = 0
  298.         colCount = 1
  299.         do i = 1, d3 
  300.            READ(*, '(A3,T5,A8,T15,A8,T25,F12.3,T40,A8,T50,F12.3)')
  301.      &            tmpConstant, tmp1Lab, tmp3Lab, tmp1Data,
  302.      &            tmp4Lab, tmp2Data
  303.  
  304.            if (Count .EQ. 0) tmpLab = tmp1Lab
  305.            Count = Count + 1
  306.            if (tmpConstant .EQ. 'RHS') then
  307.               goto 90
  308.             else
  309.               if (tmp1Lab .NE. tmpLab) then
  310.                  tmpLab = tmp1Lab
  311.                  colCount = colCount + 1
  312.               end if
  313.               k = SearchRow(tmp3Lab, rowLab, numRow)
  314.               a(k, colCount) = tmp1Data
  315.               if (tmp4Lab .NE. '        ') then
  316.                  k = SearchRow(tmp4Lab, rowLab, numRow)
  317.                  a(k, colCount) = tmp2Data
  318.               end if
  319.            endif
  320.         end do
  321.  
  322.         if (tmpConstant .NE. 'RHS') then
  323.            print *, 'Error:  too many columns'
  324.            stop
  325.         end if
  326.  
  327. 90      continue
  328.         do i = 1, d3 
  329.            READ(*, '(A4,T5,A8,T15,A8,T25,F12.3,T40,A8,T50,F12.3)')
  330.      &            tmpConstant, tmp1Lab, tmp3Lab, tmp1Data,
  331.      &            tmp4Lab, tmp2Data
  332.  
  333.            if (tmpConstant .EQ. 'ENDA') then
  334.               goto 100
  335.             else
  336.               k = SearchRow(tmp3Lab, rowLab, numRow)
  337.               a(k, nn) = tmp1Data
  338.               if (tmp4Lab .NE. '        ') then
  339.                  k = SearchRow(tmp4Lab, rowLab, numRow)
  340.                  a(k, nn) = tmp2Data
  341.               end if
  342.            endif
  343.         end do
  344.  
  345.         if (tmpConstant .NE. 'ENDA') then
  346.            print *, 'Error:  too many RHS'
  347.            stop
  348.         end if
  349.  
  350. 100     continue
  351. C    end of GetData
  352.  
  353.     end
  354.  
  355.     subroutine Exchange(rowType,rowLab,i,j)
  356.  
  357.         include 'simplex.h'
  358.         integer i, j
  359.     character*8 rowLab(d1), tmpLab
  360.     character*1 rowType(d1), tmpType
  361.  
  362.     tmpLab = rowLab(i)
  363.     tmpType = rowType(i)
  364.     rowLab(i) = rowLab(j)
  365.     rowType(i) = rowType(j)
  366.     rowLab(j) = tmpLab
  367.     rowType(j) = tmpType
  368.     end
  369.  
  370.     integer function SearchRow(label,rowLab,num)
  371.  
  372.     implicit none
  373.     integer i, num
  374.     character*8 label, rowLab(num)
  375.  
  376.     do i = 1, num
  377.         if (label .EQ. rowLab(i)) then
  378.         SearchRow = i
  379.         goto 100
  380.         endif
  381.     end do
  382.     print *, 'ERROR: unmatched row lable --- ', label
  383.   100   continue
  384.     end
  385.  
  386.  
  387.