가장 쉬운 REMC [python 3] by 바죠

가장 쉬운 REMC [python 3]


import random
import numpy as np
def functuser(x):
    case=3

    if case == 1:
       total=0.
       for j in range(len(x)):
           total+=(x[j])**2
    if case == 2:
#    Rastrigin
       total=10.*len(x)
       for j in range(len(x)):
           total+=x[j]**2-10.*np.cos(2.*np.pi*x[j])
    if case == 3:
#   Rosenbrock
       xarray0=np.zeros(len(x))
       for j in range(len(x)):
          xarray0[j]=x[j]
       total=sum(100.0*(xarray0[1:]-xarray0[:-1]**2.0)**2.0 + (1-xarray0[:-1])**2.0)
    if case == 4:
#   Styblinski-Tang
       total=0.
       for j in range(len(x)):
           total+=(x[j]**4-16.*x[j]**2+5.*x[j])/2.

    return total
class PARTICLE:
    def __init__(self,startx0,tmprt,xbounds,lverbo):
        self.position_i=[]
        self.qosition_i=[]
        self.position_best_i=[]
        self.obj_best_i=1e18
        self.obj_i=1e18
        self.dimensions=len(startx0)
        self.tmprt=tmprt
        if lverbo:
           print(self.tmprt)
        for j in range(self.dimensions):
            self.position_i.append(startx0[j]+(random.random()-0.5)*2.*np.sqrt(self.tmprt)*0.101)
        if random.random() < 0.8:
           for j in range(self.dimensions):
               self.position_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
        for j in range(self.dimensions):
            if self.position_i[j] > xbounds[j][1]:
               self.position_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
            if self.position_i[j] < xbounds[j][0]:
               self.position_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
        self.position_best_i=self.position_i.copy()
        self.qosition_i=self.position_i.copy()
    def evaluate(self,objfunct,xbounds):
        before=objfunct(self.position_i)
        for _ in range(20):
           for j in range(self.dimensions):
               self.qosition_i[j]=self.position_i[j]+(random.random()-0.5)*2.*np.sqrt(self.tmprt)*0.101
               if self.qosition_i[j] > xbounds[j][1]:
                  self.qosition_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
               if self.qosition_i[j] < xbounds[j][0]:
                  self.qosition_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
           after=objfunct(self.qosition_i)
           tmp=-(after-before)/self.tmprt
           if tmp > 300. :
              tmp=300.
           if tmp < -300. :
              tmp=-300.
           if min(1.,np.exp(tmp)) > random.random():
              before=after
              self.obj_i=after
              self.position_i=self.qosition_i.copy()
           if self.obj_i < self.obj_best_i :
              self.position_best_i=self.position_i.copy()
              self.obj_best_i=self.obj_i
        for _ in range(20):
           for j in range(self.dimensions):
               self.qosition_i[j]=self.position_i[j]+(random.random()-0.5)*2.*np.sqrt(self.tmprt)*0.101
               if self.qosition_i[j] > xbounds[j][1]:
                  self.qosition_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
               if self.qosition_i[j] < xbounds[j][0]:
                  self.qosition_i[j]=xbounds[j][0]+(xbounds[j][1]-xbounds[j][0])*random.random()
           after=objfunct(self.qosition_i)
           tmp=-(after-before)/self.tmprt
           if tmp > 300. :
              tmp=300.
           if tmp < -300. :
              tmp=-300.
           if min(1.,np.exp(tmp)) > random.random():
              before=after
              self.obj_i=after
              self.position_i=self.qosition_i.copy()
           if self.obj_i < self.obj_best_i :
              self.position_best_i=self.position_i.copy()
              self.obj_best_i=self.obj_i
class REMC():
    def __init__(self, objfunct, startx0, xbounds, nparticles, maxiter, verbose=False):
        obj_best_g=1e18
        position_best_g=[]
        swarm=[]
        tpset=[]
        x1vec=[]
        x2vec=[]
        for i in range(nparticles):
            tmprt=0.01+1.0*float(i)/float(nparticles-1)
            tpset.append(tmprt)
            swarm.append(PARTICLE(startx0,tmprt,xbounds,verbose))
        it=0
        while it < maxiter:
            if verbose:
               print(f'iter: {it:>6d} best solution: {obj_best_g:16.8e}')
            for i in range(nparticles):
                swarm[i].evaluate(objfunct,xbounds)
                if swarm[i].obj_i < obj_best_g :
                   position_best_g=list(swarm[i].position_best_i)
                   obj_best_g=float(swarm[i].obj_best_i)
            lxcd=False
            for i in range(nparticles-1,0,-1):
                if lxcd == True:
                   lxcd=False
                   continue
                if lxcd == False:
                   x1vec=list(swarm[i].position_i)
                   x2vec=list(swarm[i-1].position_i)
                   tmp=(1./tpset[i]-1./tpset[i-1])*(swarm[i].obj_i-swarm[i-1].obj_i)
                   if tmp > 300. :
                      tmp=300.
                   if tmp < -300. :
                      tmp=-300.
                   if min(1.,np.exp(tmp)) > random.random():
                      lxcd=True
                      swarm[i].position_i=x2vec.copy()
                      swarm[i-1].position_i=x1vec.copy()
                      print('exchanged',i,i-1)
            it+=1
        print('\nfinal solution:')
        print(f'   > {position_best_g}')
        print(f'   > {obj_best_g}\n')
        if True:
           abc=np.zeros(nparticles)
           abcvec=np.zeros((nparticles,len(startx0)))
           for i in range(nparticles):
               abc[i]=swarm[i].obj_best_i
               abcvec[i]=swarm[i].position_best_i
           idx=abc.argsort()
           abc=abc[idx]
           abcvec=abcvec[idx,:]
           for i in range(nparticles):
               print(abc[i])
               print(abcvec[i,:])

startx0=[]
xbounds=[]
for j in range(10):
    startx0.append(0.)
for j in range(len(startx0)):
    xbounds.append((-20., 20.))
REMC(functuser, startx0, xbounds, nparticles=50, maxiter=2000, verbose=True)


덧글

댓글 입력 영역

최근 포토로그