Changeset 2445


Ignore:
Timestamp:
Mar 22, 2010 8:20:51 PM (9 years ago)
Author:
jwatson
Message:

Refactored PySP scenario tree code, and added initialization code to (correctly) store solutions.

File:
1 edited

Legend:

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

    r2413 r2445  
    2121
    2222   """ Constructor
    23 
    2423   """
    2524   def __init__(self, name, conditional_probability, stage, reference_instance):
     
    4645      # solution (variable) values for this node. assumed to be distinct
    4746      # from self._averages, as the latter are not necessarily feasible.
    48       # objects in the map are actual variables.
     47      # objects in the map are actual pyomo Var instances; keys are
     48      # variable names.
    4949      self._solution = {}
    5050
     
    6060         # ensuring feasibility. this also leaves room for specifying infeasible
    6161         # or partial solutions.       
    62 
    6362         new_variable_index = variable._index
    64          new_variable_name = variable._name
     63         new_variable_name = variable.name
    6564         new_variable = None
    6665         if (len(new_variable_index) is 1) and (None in new_variable_index):
     
    6867         else:
    6968            new_variable = Var(new_variable_index, name=new_variable_name)
     69         new_variable.construct()
     70
     71         # by default, deactive all variable values - we're copying the
     72         # full index set of a variable, which is necessarily wasteful and
     73         # incorrect. then, do a second pass and activate those indicies
     74         # that are actually associated with this tree node.
     75         for index in new_variable_index:
     76            new_variable[index].deactivate()
     77
     78         for index in variable_indices:
     79            new_variable[index].activate()
    7080
    7181         self._solution[new_variable_name] = new_variable
     
    8999
    90100   """ Constructor
    91 
    92101   """
    93102   def __init__(self, *args, **kwds):
     
    106115
    107116   """ Constructor
    108 
    109117   """
    110118   def __init__(self, *args, **kwds):
     
    115123
    116124class ScenarioTree(object):
     125
     126   # a utility to construct the stage objects for this scenario tree.
     127   # operates strictly by side effects, initializing the self
     128   # _stages and _stage_map attributes.
     129   def _construct_stages(self, stage_ids, stage_variable_ids, stage_cost_variable_ids):
     130
     131      # construct the stage objects, which will leave them
     132      # largely uninitialized - no variable information, in particular.
     133      for stage_name in stage_ids:
     134         new_stage = Stage()
     135         new_stage._name = stage_name
     136         self._stages.append(new_stage)
     137         self._stage_map[stage_name] = new_stage
     138
     139      # initialize the variable collections (blended and cost) for each stage.
     140      # these are references, not copies.
     141      for stage_id in stage_variable_ids.keys():
     142
     143         if stage_id not in self._stage_map.keys():
     144            raise ValueError, "Unknown stage=" + stage_id + " specified in scenario tree constructor (stage->variable map)"
     145
     146         stage = self._stage_map[stage_id]
     147         variable_ids = stage_variable_ids[stage_id]
     148
     149         for variable_string in variable_ids:
     150
     151            if isVariableNameIndexed(variable_string) is True:
     152
     153               variable_name, index_template = extractVariableNameAndIndex(variable_string)
     154
     155               # validate that the variable exists and extract the reference.
     156               if variable_name not in self._reference_instance.active_components(Var):
     157                  raise ValueError, "Variable=" + variable_name + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
     158               variable = self._reference_instance.active_components(Var)[variable_name]               
     159
     160               # extract all "real", i.e., fully specified, indices matching the index template.
     161               match_indices = extractVariableIndices(variable, index_template)               
     162
     163               # there is a possibility that no indices match the input template.
     164               # if so, let the user know about it.
     165               if len(match_indices) == 0:
     166                  raise RuntimeError, "No indices match template="+str(index_template)+" for variable="+variable_name+" ; encountered in scenario tree specification for model="+self._reference_instance.name
     167                 
     168               stage._variables.append((variable, index_template, match_indices))
     169
     170            else:
     171
     172               # verify that the variable exists.
     173               if variable_string not in self._reference_instance.active_components(Var).keys():
     174                  raise RuntimeError, "Unknown variable=" + variable_string + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
     175
     176               variable = self._reference_instance.active_components(Var)[variable_string]
     177
     178               # 9/14/2009 - now forcing the user to explicit specify the full
     179               # match template (e.g., "foo[*,*]") instead of just the variable
     180               # name (e.g., "foo") to represent the set of all indices.
     181               
     182               # if the variable is a singleton - that is, non-indexed - no brackets is fine.
     183               # we'll just tag the var[None] variable value with the (suffix,value) pair.
     184               if None not in variable._index:
     185                  raise RuntimeError, "Variable="+variable_string+" is an indexed variable, and templates must specify an index match; encountered in scenario tree specification for model="+self._reference_instance.name                 
     186
     187               match_indices = []
     188               match_indices.append(None)
     189
     190               stage._variables.append((variable, "", match_indices))
     191
     192      for stage_id in stage_cost_variable_ids.keys():
     193
     194         if stage_id not in self._stage_map.keys():
     195            raise ValueError, "Unknown stage=" + stage_id + " specified in scenario tree constructor (stage->cost variable map)"
     196         stage = self._stage_map[stage_id]
     197         
     198         cost_variable_string = stage_cost_variable_ids[stage_id].value # de-reference is required to access the parameter value
     199
     200         # to be extracted from the string.
     201         cost_variable_name = None
     202         cost_variable = None
     203         cost_variable_index = None
     204
     205         # do the extraction.
     206         if isVariableNameIndexed(cost_variable_string) is True:
     207
     208            cost_variable_name, index_template = extractVariableNameAndIndex(cost_variable_string)
     209
     210            # validate that the variable exists and extract the reference.
     211            if cost_variable_name not in self._reference_instance.active_components(Var):
     212               raise ValueError, "Variable=" + cost_variable_name + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
     213            cost_variable = self._reference_instance.active_components(Var)[cost_variable_name]               
     214
     215            # extract all "real", i.e., fully specified, indices matching the index template.
     216            match_indices = extractVariableIndices(cost_variable, index_template)
     217
     218            # only one index can be supplied for a stage cost variable.
     219            if len(match_indices) != 1:
     220               raise RuntimeError, "Only one index can be specified for a stage cost variable - "+str(len(match_indices))+"match template="+index_template+" for variable="+cost_variable_name+" ; encountered in scenario tree specification for model="+self._reference_instance.name
     221
     222            cost_variable_index = match_indices[0]
     223
     224         else:
     225
     226            cost_variable_name = cost_variable_string
     227
     228            # validate that the variable exists and extract the reference
     229            if cost_variable_name not in self._reference_instance.active_components(Var):
     230               raise ValueError, "Cost variable=" + cost_variable_name + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
     231            cost_variable = self._reference_instance.active_components(Var)[cost_variable_name]
     232           
     233         # store the validated info.
     234         stage._cost_variable = (cost_variable, cost_variable_index)
    117235
    118236   """ Constructor
     
    190308      # construct the stage objects w/o any linkages first; link them up
    191309      # with tree nodes after these have been fully constructed.
    192       for stage_name in stage_ids:
    193          new_stage = Stage()
    194          new_stage._name = stage_name
    195          self._stages.append(new_stage)
    196          self._stage_map[stage_name] = new_stage
     310      self._construct_stages(stage_ids, stage_variable_ids, stage_cost_variable_ids)
    197311
    198312      # construct the tree node objects themselves in a first pass,
     
    260374         self._scenarios.append(new_scenario)
    261375         self._scenario_map[scenario_name] = new_scenario
    262 
    263       # map the variables to the stages - these are references, not copies.
    264       for stage_id in stage_variable_ids.keys():
    265 
    266          if stage_id not in self._stage_map.keys():
    267             raise ValueError, "Unknown stage=" + stage_id + " specified in scenario tree constructor (stage->variable map)"
    268 
    269          stage = self._stage_map[stage_id]
    270          variable_ids = stage_variable_ids[stage_id]
    271 
    272          for variable_string in variable_ids:
    273 
    274             if isVariableNameIndexed(variable_string) is True:
    275 
    276                variable_name, index_template = extractVariableNameAndIndex(variable_string)
    277 
    278                # validate that the variable exists and extract the reference.
    279                if variable_name not in self._reference_instance.active_components(Var):
    280                   raise ValueError, "Variable=" + variable_name + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
    281                variable = self._reference_instance.active_components(Var)[variable_name]               
    282 
    283                # extract all "real", i.e., fully specified, indices matching the index template.
    284                match_indices = extractVariableIndices(variable, index_template)               
    285 
    286                # there is a possibility that no indices match the input template.
    287                # if so, let the user know about it.
    288                if len(match_indices) == 0:
    289                   raise RuntimeError, "No indices match template="+str(index_template)+" for variable="+variable_name+" ; encountered in scenario tree specification for model="+self._reference_instance.name
    290                  
    291                stage._variables.append((variable, index_template, match_indices))
    292 
    293             else:
    294 
    295                # verify that the variable exists.
    296                if variable_string not in self._reference_instance.active_components(Var).keys():
    297                   raise RuntimeError, "Unknown variable=" + variable_string + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
    298 
    299                variable = self._reference_instance.active_components(Var)[variable_string]
    300 
    301                # 9/14/2009 - now forcing the user to explicit specify the full
    302                # match template (e.g., "foo[*,*]") instead of just the variable
    303                # name (e.g., "foo") to represent the set of all indices.
    304                
    305                # if the variable is a singleton - that is, non-indexed - no brackets is fine.
    306                # we'll just tag the var[None] variable value with the (suffix,value) pair.
    307                if None not in variable._index:
    308                   raise RuntimeError, "Variable="+variable_string+" is an indexed variable, and templates must specify an index match; encountered in scenario tree specification for model="+self._reference_instance.name                 
    309 
    310                match_indices = []
    311                match_indices.append(None)
    312 
    313                stage._variables.append((variable, "", match_indices))
    314 
    315       for stage_id in stage_cost_variable_ids.keys():
    316 
    317          if stage_id not in self._stage_map.keys():
    318             raise ValueError, "Unknown stage=" + stage_id + " specified in scenario tree constructor (stage->cost variable map)"
    319          stage = self._stage_map[stage_id]
    320          
    321          cost_variable_string = stage_cost_variable_ids[stage_id].value # de-reference is required to access the parameter value
    322 
    323          # to be extracted from the string.
    324          cost_variable_name = None
    325          cost_variable = None
    326          cost_variable_index = None
    327 
    328          # do the extraction.
    329          if isVariableNameIndexed(cost_variable_string) is True:
    330 
    331             cost_variable_name, index_template = extractVariableNameAndIndex(cost_variable_string)
    332 
    333             # validate that the variable exists and extract the reference.
    334             if cost_variable_name not in self._reference_instance.active_components(Var):
    335                raise ValueError, "Variable=" + cost_variable_name + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
    336             cost_variable = self._reference_instance.active_components(Var)[cost_variable_name]               
    337 
    338             # extract all "real", i.e., fully specified, indices matching the index template.
    339             match_indices = extractVariableIndices(cost_variable, index_template)
    340 
    341             # only one index can be supplied for a stage cost variable.
    342             if len(match_indices) != 1:
    343                raise RuntimeError, "Only one index can be specified for a stage cost variable - "+str(len(match_indices))+"match template="+index_template+" for variable="+cost_variable_name+" ; encountered in scenario tree specification for model="+self._reference_instance.name
    344 
    345             cost_variable_index = match_indices[0]
    346 
    347          else:
    348 
    349             cost_variable_name = cost_variable_string
    350 
    351             # validate that the variable exists and extract the reference
    352             if cost_variable_name not in self._reference_instance.active_components(Var):
    353                raise ValueError, "Cost variable=" + cost_variable_name + " associated with stage=" + stage_id + " is not present in model=" + self._reference_instance.name
    354             cost_variable = self._reference_instance.active_components(Var)[cost_variable_name]
    355            
    356          # store the validated info.
    357          stage._cost_variable = (cost_variable, cost_variable_index)
    358376
    359377      # for output purposes, it is useful to known the maximal length of identifiers
Note: See TracChangeset for help on using the changeset viewer.