Changeset 2451


Ignore:
Timestamp:
Mar 24, 2010 11:15:35 PM (9 years ago)
Author:
jwatson
Message:

Modified scenario tree class in PySP to not create solution attributes on tree nodes (which is expensive) until it is required.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • coopr.pysp/trunk/coopr/pysp/scenariotree.py

    r2450 r2451  
    2020class ScenarioTreeNode(object):
    2121
     22   #
     23   # initialize the _solutions attribute of a tree node.
     24   #
     25
     26   def _initialize_solutions(self):
     27
     28      # NOTE: Given the expense, this should really be optional - don't
     29      #       construct unless we're actually going to use!
     30      # for each variable referenced in the stage, clone the variable
     31      # for purposes of storing solutions. we are being wasteful in
     32      # terms copying indices that may not be referenced in the stage.
     33      # this is something that we might revisit if space/performance
     34      # is an issue (space is the most likely issue)
     35      for variable, match_template, variable_indices in self._stage._variables:
     36
     37         # don't bother copying bounds for variables, as the values stored
     38         # here are computed elsewhere - and that entity is responsible for
     39         # ensuring feasibility. this also leaves room for specifying infeasible
     40         # or partial solutions.       
     41         new_variable_index = variable._index
     42         new_variable_name = variable.name
     43         new_variable = None
     44         if (len(new_variable_index) is 1) and (None in new_variable_index):
     45            new_variable = Var(name=new_variable_name)
     46         else:
     47            new_variable = Var(new_variable_index, name=new_variable_name)
     48         new_variable.construct()
     49
     50         # by default, deactive all variable values - we're copying the
     51         # full index set of a variable, which is necessarily wasteful and
     52         # incorrect. then, do a second pass and activate those indicies
     53         # that are actually associated with this tree node.
     54         for index in new_variable_index:
     55            new_variable[index].deactivate()
     56
     57         for index in variable_indices:
     58            new_variable[index].activate()
     59
     60         self._solutions[new_variable_name] = new_variable
     61
     62      self._solutions_initialized = True
     63     
     64
    2265   """ Constructor
    2366   """
    24    def __init__(self, name, conditional_probability, stage, reference_instance):
     67   def __init__(self, name, conditional_probability, stage, initialize_solution=False):
    2568
    2669      self._name = name
     
    4689      self._maximums = {}
    4790
     91      # a flag indicating whether the _solutions attribute has been properly initialized.
     92      self._solutions_initialized = False
     93
    4894      # solution (variable) values for this node. assumed to be distinct
    4995      # from self._averages, as the latter are not necessarily feasible.
     
    5298      self._solutions = {}
    5399
    54       # NOTE: Given the expense, this should really be optional - don't
    55       #       construct unless we're actually going to use!
    56       # for each variable referenced in the stage, clone the variable
    57       # for purposes of storing solutions. we are being wasteful in
    58       # terms copying indices that may not be referenced in the stage.
    59       # this is something that we might revisit if space/performance
    60       # is an issue (space is the most likely issue)
    61       for variable, match_template, variable_indices in self._stage._variables:
    62 
    63          # don't bother copying bounds for variables, as the values stored
    64          # here are computed elsewhere - and that entity is responsible for
    65          # ensuring feasibility. this also leaves room for specifying infeasible
    66          # or partial solutions.       
    67          new_variable_index = variable._index
    68          new_variable_name = variable.name
    69          new_variable = None
    70          if (len(new_variable_index) is 1) and (None in new_variable_index):
    71             new_variable = Var(name=new_variable_name)
    72          else:
    73             new_variable = Var(new_variable_index, name=new_variable_name)
    74          new_variable.construct()
    75 
    76          # by default, deactive all variable values - we're copying the
    77          # full index set of a variable, which is necessarily wasteful and
    78          # incorrect. then, do a second pass and activate those indicies
    79          # that are actually associated with this tree node.
    80          for index in new_variable_index:
    81             new_variable[index].deactivate()
    82 
    83          for index in variable_indices:
    84             new_variable[index].activate()
    85 
    86          self._solutions[new_variable_name] = new_variable
     100      if initialize_solution is True:
     101         self._initialize_solutions()
    87102
    88103   #
     
    92107
    93108   def snapshotSolutionFromAverages(self):
     109
     110      if self._solutions_initialized is False:
     111         self._initialize_solutions()     
    94112
    95113      for variable_name, variable in self._solutions.items():
     
    113131
    114132   def snapshotSolutionFromInstances(self, scenario_instance_map):
     133
     134      if self._solutions_initialized is False:
     135         self._initialize_solutions()     
    115136
    116137      for variable_name, variable in self._solutions.items():
Note: See TracChangeset for help on using the changeset viewer.