⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmd_node__define.pro

📁 该程序是基于IDL平台下开法的应用随机搜索树进行搜索的优化算法实例!
💻 PRO
📖 第 1 页 / 共 2 页
字号:
 ;+
; NAME:
;
;  RMD_NODE__DEFINE
;
; PURPOSE:
;
;  Class definition for a tree node.  It inherits from an
;  IDL_CONTAINER class and can contain other nodes.  Instance
;  data includes parameters, parameter ranges, an ID specified
;  externally.
;
;  This class definition was written primarily for application
;  to minimization.  A UI wrapper was written for it called
;  TREE_MIN_UI that provides an interface for minimization of
;  a function of a single variable.  The implementation is
;  a global minimization search strategy and provides an
;  example use of this class.
;
; AUTHOR:
;
;  Robert Dimeo
;  NIST Center for Neutron Research
;  National Institute of Standards and Technology
;  100 Bureau Drive-Stop 8562
;  Gaithersburg, MD 20899
;
; CATEGORY:
;
;  OPTIMIZATION
;
; CALLING SEQUENCE:
;
;  IDL> o = OBJ_NEW("RMD_NODE",  PRANGE = [-5.0,5.0],       $
;                                LEVEL = 1,                 $
;                                FUNC = 'MY_MIN_FUNC',      $
;                                DECAY_WIDTH = 3.0,         $
;                                INCREMENT_VALUE = 10,      $
;                                _EXTRA = extra             )
;
;     The requirements on the function, in this case "MY_MIN_FUNC" are
;     that it be written as a FUNCTION, it accepts the parameters with
;     which the minimization is performed with respect to, and it accepts
;     keyword parameters via EXTRA keyword inheritance.  Therefore the
;     function might be written as follows:
;
;           FUNCTION MY_MIN_FUNC,x,_EXTRA = extra
;           y = cos(3.0*x)
;           RETURN,y
;           END
;
; EXAMPLE USAGE:
;
;  A simple example of using this class for minimizing a function
;  of a single variable is shown at the end of this code listing
;  and it is called TEST_NODE_MIN.  A more in-depth example is
;  shown in the program named TREE_MIN_UI which is much more
;  interactive and illustrates how the tree evolves with each
;  successive iteration.
;
; REQUIREMENTS:
;
;  IDL 6.0 and higher
;
; REQUIRED PROGRAMS:
;
;  NONE
;
; COMMON BLOCKS:
;
;  NONE
;
; MODIFICATION HISTORY:
;
;  RMD -- Wrote 10/22/04
;
;-
; ************************************ ;
pro rmd_node::cleanup
ptr_free,self.prange_ptr,self.pextra
self->idl_container::cleanup
end
; ************************************ ;
function find_rmd_node_by_id,oref,id_to_match
; This is a recursive function that returns an object
; reference if there is a node object in the object
; hierarchy that matches the id_to_match.
;
; Note that this function is not used anywhere within this
; code but it might be useful in applications
; that use this class.(?)
if n_params() ne 2 then return,0
oref->get_property,id = id
if (id eq id_to_match) then return,oref
nchildren = oref->count()
if nchildren eq 0 then return,0
child = oref->get(/all)
for i = 0,nchildren-1 do begin
   result = find_rmd_node_by_id(child[i],id_to_match)
   if obj_valid(result) then return,result
endfor
return,0
end
; ************************************ ;
function rmd_node::terminated
return,(self->count()) eq 0
end
; ************************************ ;
pro rmd_node::get_property,   parms = parms,                      $
                              prange = prange,                    $
                              id = id,                            $
                              visits = visits,                    $
                              nsubdiv = nsubdiv,                  $
                              level = level,                      $
                              node_value = node_value,            $
                              func = func,                        $
                              parent_node = parent_node,          $
                              branch_value = branch_value,        $
                              increment_value = increment_value

increment_value = self.increment_value
if arg_present(parent_node) then parent_node = self.parent_node
if arg_present(parms) then begin
   ; Get the ranges out
   prange = *self.prange_ptr
   parms = prange[0,*]+0.5*(prange[1,*]-prange[0,*])
endif
if arg_present(prange) then prange = *self.prange_ptr
func = self.func
visits = self.visits
nsubdiv = self.nsubdiv
id = self.id
level = self.level
node_value = self.node_value
branch_value = self.branch_value
end
; ************************************ ;
function rmd_node::increment_branch_value
self.branch_value = self.branch_value + self.increment_value
return,1
end
; ************************************ ;
function rmd_node::decrement_branch_value
; The "probability decay" implementation
branch_value = self.branch_value - 1
arg = float(self.visits)/self.decay_width
self.branch_value = 1L+long(branch_value*exp(-0.5*arg^2))
return,1
end
; ************************************ ;
function rmd_node::get_new_ranges
; This finds the new ranges based on the current
; parameter ranges.

self->get_property,nsubdiv = nsubdiv,prange = prange
s = size(prange)
if s[0] eq 1 then np = 1 else np = s[2]
new_ranges = fltarr(2,np,nsubdiv)
count = 0L

for i = 0,np-1 do begin
   delta = prange[1,i] - prange[0,i]   ; This is the spread
                                       ; for a particular parameter
   ; We subdivide this range into NSUBDIV
   ; ranges and create the new ranges
   new_delta = delta/nsubdiv
   for j = 0,nsubdiv-1 do begin
      pplo = prange[0,i]+j*new_delta
      pphi = prange[0,i]+(j+1)*new_delta
      new_ranges[*,i,j] = [pplo,pphi]
      count++
   endfor
endfor

; Now we have to find all possible combinations of
; pairing up ranges of each parameter.  Note that
; currently this only works properly when this is a
; binary tree.

count = 0L
ntotal = nsubdiv^np
index_arr = intarr(np,nsubdiv^np)

bit=bytarr(np)
for i=0,2^np-1 do begin
   result=i
   for k=0,np-1 do begin
      valby2=result/2
      bit[k]=result-valby2*2
      result=valby2
   endfor
   index_arr[*,i] = fix(bit)
endfor

index_arr = index_arr+1
match_arr = (1+indgen(np)) # (replicate(1,nsubdiv^np))
output_range = fltarr(2,np,nsubdiv^np)
for i = 0,2^np-1 do begin
   for j = 0,np-1 do begin
      xi = match_arr[j,i]-1
      yi = index_arr[j,i]-1
      output_range[*,j,i] = new_ranges[*,xi,yi]
   endfor
endfor

return,output_range
end
; ************************************ ;
function rmd_node::add_nodes,next_index
if n_params() eq 0 then next_index = 1
index = strtrim(string(next_index),2)
; Add new nodes one level deeper
new_level = self.level + 1L
new_ranges = self->get_new_ranges()
new_best = 0B
n_ranges = (size(new_ranges))[3]
for i = 0,n_ranges - 1 do begin
   index = strtrim(string(next_index),2)
   id = strtrim(string(new_level),2)+'-'+index
   onew = obj_new('rmd_node',id, prange = new_ranges[*,*,i],               $
                                 level = new_level,                        $
                                 parent_node = self,                       $
                                 func = self.func,                         $
                                 decay_width = self.decay_width,           $
                                 increment_value = self.increment_value,   $
                                 _Extra = *self.pextra                     )
   self->add,onew
   next_index++
endfor
return,1
end
; ************************************ ;
function rmd_node::add_visit
self.visits = self.visits + 1L
return,1
end
; ************************************ ;
function rmd_node::evaluate_function
self->get_property,parms = parms
self.node_value = call_function(self.func,transpose(parms),_Extra = *self.pextra)
return,1
end
; ************************************ ;
function rmd_node::go_to_the_top, increase = increase,decrease = decrease
self->get_property,parent_node = parent
if keyword_set(increase) then ret = self->increment_branch_value()
if ~obj_valid(parent) then return,0
while obj_valid(parent) do begin
   ; Increment the parent's branch value
   parent->get_property,id = id,branch_value = branch_value

   if keyword_set(increase) then ret = parent->increment_branch_value()
   if keyword_set(decrease) then ret = parent->decrement_branch_value()
   parent->get_property,parent_node = next_parent_up
   parent = next_parent_up
endwhile

return,1
end
; ************************************ ;
pro rmd_node::set_property,   prange = prange,        $
                              level = level,          $
                              func = func,            $
                              node_value = node_value

if n_elements(node_value) ne 0 then self.node_value = node_value
if n_elements(func) ne 0 then self.func = func
if n_elements(level) ne 0 then self.level = level
if n_elements(prange) ne 0 then *self.prange_ptr = prange
if n_elements(nsubdiv) ne 0 then self.nsubdiv = nsubdiv
end
; ************************************ ;
function rmd_node::init,   id,                                 $
                           prange = prange,                    $
                           level = level,                      $
                           parent_node = parent_node,          $
                           increment_value = increment_value,  $
                           func = func,                        $
                           decay_width = decay_width,          $

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -