main page (gr) home main page

In Support of my candidacy to ICANN nomination!


        program SIML

! Program (in fortran90) to simulate a large message list. 

! Copyright Constantine S. Chassapis -- 25 Aug, 2000.

! contact me at cschassapis@acm.org

! Description: See the MEMO and related emails: here.
! Output to a classic console. No windows,
! just calculations. Iterative dynamic loop. First all
! list-members act, then the robot requests SUM-UPs and
! does some acoounting, and finally collectors (if there
! are any) are asked by the robot (the program) to form
! collections. Then the loop is repeated.

! Each user has six attribures:
!  user(i,atrrib.j), i=1..N, j=1..6:
!   attr.1 == attrib.activity: -1,0,+1: denied, notActive, active
!   attr.2 == attrib.points: integer unlimited
!   attr.3 == attrib.hasPosted: 1, 0, (yes,no)
!   attr.4 == attrib.isThreaded: -1, 0, +1: notResponded, no, yes
!   attr.5 == attrib.isCollector: 1, 0, (yes,no) !for minimizing point-comparisons
!   attr.6 == attrib.worker: five-valued: 
!             tourist,lazy,average,hardworker,exceptional
!
! The pointing system currently programmed is:
! A. Per member:
!  pentr:  +100 at entry.
!  pmess:  +0   per message posted.
!  psump:  +1   per SUM UP done.
!  psnot:  -10  per SUM UP not done but required.
!  pimpr:  -1   per improper message.
!  pthrd:  +1   per message that starts a thread
!  plink:  +1   per message that is linked back in a collector's collection.
!  pcoll:  +1   for a collection given to the collector
! B. If member points greater than +300 then COLLECTOR.
! C. If member points less than -100 then provisional denial of 
!    message posting capability.

! This program if run outputs after 10000 steps:
!  time  thrds   msgs  oksum  nosum  links  colex denied colectr active  avepoi
! 10000    440   1800    170     45   2445    250    550    3800  10650     862

! and after 100000 steps:
!  time  thrds   msgs  oksum  nosum  links  colex denied colectr active  avepoi
!100000    424   1571    184     68   1447    172    563    4165  10272    8475

! Note that the above values are not average values except for the averaged points.

! According to the characteristics of the list (number of users, distribution
! of eagerness to work, various activity percentages) different pointing
! systems will produce stability. The user must experiment.



! DEFINE

        implicit none

! number of active members of the list
        integer numus
        parameter (numus=15000)

! the users:
        integer users(numus,6)

! user attributes:
        integer activ, points, hasPost, isThrd, isColl, workr
        parameter (activ=1, points=2, hasPost=3, isThrd=4, isColl=5, workr=6)

! pointing system:
        integer pentr, pmess, psump, psnot, pimpr, pthrd, plink, pcoll
        parameter (pentr=100, pmess=0, psump=1, psnot=-10, pimpr=-1, pthrd=1, plink=1, pcoll=1)

! various aux variables:
        real unif, ran, response, avepoi, ran2
        integer iu, iu2, iattr, iseed, it, tolink, ilink, itime,iseed0
        integer tcount, mcount, dcount, ccount, acount, lcount, icollx
        integer oksum, nosum
        logical found

!   INITIALIZE

        iseed=-1
        iseed0=-1
        unif=ran2(iseed)
        unif=ran(iseed0)

        do 100, iu = 1, numus

          users(iu,activ)=+1       !activity
          users(iu,points)=pentr   !points: unlimited
          users(iu,hasPost)=0      !hasPosted
          users(iu,isThrd)=0       !isThreaded
          users(iu,isColl)=0       !isCollector: binary
          
          unif=ran2(iseed)

! the users are distributed as follows:
! (tourist,lazy,average,hardworker,exceptional)=(5%,30%,40%,20%,5%)

          if (unif.le.0.4)then
             users(iu,workr)=+3   !worker: average. Fills 40%.
          else if (unif.le.0.7.and.unif.gt.0.4) then 
             users(iu,workr)=+2   !worker: lazy. Fills 30%.
          else if (unif.le.0.9.and.unif.gt.0.7) then 
             users(iu,workr)=+4   !worker: hard. Fills 20%.
          else if (unif.le.0.95.and.unif.gt.0.9) then 
             users(iu,workr)=+1   !worker: tourist. Fills 5%.
          else if (unif.le.1.0.and.unif.gt.0.95) then 
             users(iu,workr)=+5   !worker: exceptional. Fills 5%.
          else
             stop '1 should never arrive here'
          endif

 100    continue


! Total simulation steps (time).
        itime=100000

!   RUN
        print*,'  time  thrds   msgs  oksum  nosum  links  colex denied colectr active  avepoi'

        do 300, it = 1, itime
        
        tcount = 0
        mcount = 0
        dcount = 0
        ccount = 0
        acount = 0
        avepoi = 0.
        lcount = 0
        icollx = 0
        oksum = 0
        nosum = 0

!       users actions

! the particular percentages (3%,13%,84%) were sellected so
! to have a given activity of messages and threads per step.

! We also allow for a 10% of improper messages per step.

        do 410, iu=1,numus
           if (users(iu,activ).eq.1)then
              unif=ran2(iseed)
              if (unif.le.0.03) then   ! fills 3%
                 if (users(iu,hasPost).eq.1) then
                     users(iu,isThrd) = +1
                     users(iu,points) = users(iu,points) + pthrd
                     tcount = tcount + 1
                 endif
              else if (unif.le.0.16.and.unif.gt.0.03)then  ! fills 13%
                 unif=ran(iseed0)
                 if (unif.le.0.9) then ! fills 90%
                    unif=ran2(iseed)
                    if (unif.le.response(users(iu,workr),users(iu,points))) then
                       users(iu,points) =  users(iu,points) + pmess 
                       users(iu,hasPost) = +1
                       mcount = mcount + 1
                    endif
                 else if (unif.le.1.0.and.unif.gt.0.9) then ! fills 10%
                    unif=ran2(iseed)
                    if (unif.le.response(users(iu,workr),users(iu,points))) then
                       users(iu,points) =  users(iu,points) + pimpr 
                       users(iu,hasPost) = +1
                       mcount = mcount + 1
                    endif
                 else
                    stop '3: should never arrive here'
                 endif   
              else if (unif.le.1.0000.and.unif.gt.0.16)then  ! fills 84%
                 ! do nothing
              else
                 stop '2: should never arrive here'
              endif
           endif
 410    continue


!       robot actions

! the particular percentages (2%,98%) were sellected so
! to have a given activity of SUM-UPs per step.

        do 430, iu=1, numus

           if (users(iu,activ).ne.0)then
              unif=ran(iseed0)
              if (unif.le.0.02) then ! fills 2%
                 if(users(iu,isThrd).eq.0)then
                    unif=ran2(iseed)
                    if (unif.le.response(users(iu,workr),users(iu,points))) then
                       do 433, iu2 = 1, numus
                          found=(users(iu2,isThrd).eq.-1)
                          if(found)goto 434
 433                   continue
 434                   continue
                       if(found)then
                           users(iu,points) = users(iu,points) + psump 
                           users(iu2,isThrd) = 0
                           oksum = oksum + 1
                       endif
                    endif
                 elseif(users(iu,isThrd).eq.+1)then
                    unif=ran2(iseed)
                    if (unif.le.response(users(iu,workr),users(iu,points))) then
                       users(iu,points) = users(iu,points) + psump
                       users(iu,isThrd) = 0
                       oksum = oksum + 1
                       mcount = mcount + 1
                    else
                       users(iu,isThrd) = -1
                       users(iu,points) = users(iu,points) + psnot
                       nosum = nosum + 1
                    endif
                 endif
              else ! fills 98%
                 ! do nothing
              endif
           endif

           ! just accounting
           if (users(iu,points) .lt. -100 ) then
                users(iu, activ) = -1
                users(iu, isColl) = 0
                dcount = dcount + 1
           elseif (users(iu,points).ge.-100.and.users(iu,points).lt.+300) then
                users(iu, activ) = +1
                users(iu, isColl) = 0
                acount = acount + 1
           elseif(users(iu,points) .ge. +300 ) then
                users(iu, isColl)=+1
                ccount = ccount + 1
           endif

           avepoi = avepoi + users(iu,points)

 430    continue

!       collectors actions

! the particular percentages (8%,92%) were sellected so
! to have a given activity of collections per step.

        do 450, iu=1,numus
           if (users(iu,activ).eq.1.and.users(iu,isColl).eq.1)then
              unif=ran(iseed0)
              if (unif.le.0.08) then ! fills 8%
                  unif=ran2(iseed)
                  if (unif.le.response(users(iu,workr),users(iu,points))) then
                       users(iu,points) = users(iu,points) + pcoll
                       mcount = mcount + 1
                       unif = ran2(iseed)
                       tolink = max(nint(mcount*unif/100.),1)
                       ilink = 0
                       do 457, iu2 = 1, numus
                          if(users(iu2,hasPost).eq.1)then
                                ilink = ilink + 1
                                if (ilink.gt.tolink)goto 458
                                users(iu2,points) = users(iu2,points) + plink
                          endif
 457                   continue
 458                   continue
                       lcount = lcount + ilink
                       icollx = icollx + 1
                  endif
              else ! fills 92%
                 !do nothing
              endif
           endif
 450    continue


        write(*,'(10(1x,i6),1x,f8.1)')it,tcount, mcount, oksum, nosum, lcount, icollx, dcount, ccount, acount, (avepoi/numus)

        if(mod(it,15).eq.0) print*,'  time  thrds   msgs  oksum  nosum  links  colex denied colectr active  avepoi'

 300    continue

        end program SIML


!---------*---------*---------*---------*---------*---------*---------*-

        real FUNCTION RAN(ISEED)
!       Numerical Recipes (1st ed.) routine RAN.
        PARAMETER(IA=7141,IC=54773,IM=259200)
        ISEED=MOD(ISEED*IA+IC,IM)
        RAN=FLOAT(ISEED)/FLOAT(IM)
        RETURN
        END

!---------*---------*---------*---------*---------*---------*---------*-

        real function response(user, points)

! routine that defines the responsiveness of the list-members. Note
! that responsiveness declines as the user gets more points. Note
! also that there are asymptotes at 0% and at 100%. 

        integer user, points
        integer tourist,lazy,average,hardw,exception
        parameter (tourist=1,lazy=2,average=3,hardWorker=4,exceptional=5)
        real x0,xscal


        if(user.eq.tourist)then
            x0=-400.
            xscal=100.
        elseif(user.eq.lazy)then
            x0=-200.
            xscal=300.
        elseif(user.eq.average)then
            x0=0.
            xscal=300.
        elseif(user.eq.hardWorker)then
            x0=500.
            xscal=300.
        elseif(user.eq.exceptional)then
            x0=1000.
            xscal=300.
        else
            stop '9 should never arrive here'
        endif

! sigmoid response. Gives 1 if points tend to a large negative
! number and gives 0 if points tend to large positive number.

        response = 1.-tanh((real(points)-x0)/xscal)/2.

        end


!---------*---------*---------*---------*---------*---------*---------*-


       real function ran2(idum)

!          version 1.0.2    of 21/6/97.

!  Numerical Recipes (1st ed.) routine RAN2.
!  Only 714 025 differend randoms between 0 and 1 are possible as output.
!  Set or Reset the sequence by giving a negative to idum, otherwise do
!  not change it.

       implicit none
       integer j, m, ia, ic, iff, idum, iy
       real rm
       parameter(m=714025, ia=1366, ic=150889, rm=1./m)

       integer ir(97)

       data iff /0/

       if(idum.lt.0.or.iff.eq.0)then
         iff=1
         idum=mod(ic-idum,m)
         do 11, j=1,97
           idum=mod(ia*idum+ic,m)
           ir(j)=idum
 11      continue
         idum=mod(ia*idum+ic,m)
         iy=idum
       endif

       j = 1+(97*iy)/m

       if(j.gt.97.or.j.lt.1)then
          stop'ran2 stop. check!'
       endif

       iy=ir(j)
       ran2=iy*rm
       idum=mod(ia*idum+ic,m)
       ir(j)=idum

       end


If you have something to say about anything in this page, please, communicate! Contact me at cschassapis@acm.org or write your thoughts into amorphous.art guestbook. But, if you download and save this page to your machine, or print this page, then, please send me an e-mail saying that you did that. Thanks.


Last updated: Aug 25, 2000


main page (gr) home main page