Changeset 2172


Ignore:
Timestamp:
Jan 26, 2010 10:27:46 PM (10 years ago)
Author:
jwatson
Message:

Preliminary functionality to support scenario bundling - modified the scenario tree constructor to take a list of scenarios to retain; all other information is culled. Next up is correct re-scaling of the probabilities.

File:
1 edited

Legend:

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

    r1998 r2172  
    9090   """ Constructor
    9191       Arguments:
    92            model                         the (deterministic) model associated with this scenario tree
    93            nodes              (type-TBD) set of tree node IDs
    94            nodechildren       (type-TBD) map of node ID to a set of IDs indicating child nodes.
    95            nodestages         (type-TBD) map of tree node ID to stage ID
    96            nodeprobabilities  (type-TBD) map of node ID to corresponding conditional probability
    97            stages             (type-TBD) ordered set of stage IDs
    98            scenarios          (type-TBD) set of scenario node IDs
    99            scenarioleafs      (type-TBD) map of scenario ID to leaf tree node ID
    100            stagevariables     (type-TBD) map of stage ID to the names of the variables in the corresponding stage.
    101            stagecostvariables (type-TBD) map of stage ID to the name of the cost variable for the corresponding stage.
    102            nodedata           (type-TBD) map of node ID to the name of the corresponding data file (prefix only - no .dat suffix).
    103            scenariobaseddata  (type-TBD) parameter indicating whether instance data comes from scenario-based or node-based .dat files.
    104    """
     92           model                           the (deterministic) model associated with this scenario tree
     93           nodes                (type-TBD) set of tree node IDs
     94           nodechildren         (type-TBD) map of node ID to a set of IDs indicating child nodes.
     95           nodestages           (type-TBD) map of tree node ID to stage ID
     96           nodeprobabilities    (type-TBD) map of node ID to corresponding conditional probability
     97           stages               (type-TBD) ordered set of stage IDs
     98           scenarios            (type-TBD) set of scenario node IDs
     99           scenarioleafs        (type-TBD) map of scenario ID to leaf tree node ID
     100           stagevariables       (type-TBD) map of stage ID to the names of the variables in the corresponding stage.
     101           stagecostvariables   (type-TBD) map of stage ID to the name of the cost variable for the corresponding stage.
     102           nodedata             (type-TBD) map of node ID to the name of the corresponding data file (prefix only - no .dat suffix).
     103           scenariobaseddata    (type-TBD) parameter indicating whether instance data comes from scenario-based or node-based .dat files.
     104           scenariobundlelist (type-TBD) a list of scenario names to retain, i.e., cull the rest to create a reduced tree!
     105   """ 
    105106   def __init__(self, *args, **kwds):
    106107      self._name = None # TBD - some arbitrary identifier
     
    139140      scenario_leaf_ids = None
    140141      scenario_based_data = None
     142      scenario_bundle_list = None
    141143
    142144      # process the keyword options
     
    164166         elif key == "scenariobaseddata":
    165167            scenario_based_data = kwds[key]           
     168         elif key == "scenariobundlelist":
     169            scenario_bundle_list = kwds[key]           
    166170         else:
    167171            print "Unknown option=" + key + " specified in call to ScenarioTree constructor"
     
    382386      self.computeIdentifierMaxLengths()
    383387
     388      # if a sub-bundle of scenarios has been specified, mark the
     389      # active scenario tree components and compress the tree.
     390      if scenario_bundle_list is not None:
     391         print "Compressing scenario tree!"
     392         self.compress(scenario_bundle_list)
     393
     394   #
     395   # utility for compressing or culling a scenario tree based on
     396   # a provided list of scenarios (specified by name) to retain -
     397   # all non-referenced components are eliminated. this particular
     398   # method compresses *in-place*, i.e., via direct modification
     399   # of the scenario tree structure.
     400   #
     401   def compress(self, scenario_bundle_list):
     402
     403      # scan for and mark all referenced scenarios and
     404      # tree nodes in the bundle list - all stages will
     405      # obviously remain.
     406      for scenario_name in scenario_bundle_list:
     407         if scenario_name not in self._scenario_map:
     408            raise ValueError, "Scenario="+scenario_name+" selected for bundling not present in scenario tree"
     409         scenario = self._scenario_map[scenario_name]
     410         scenario.retain = True
     411
     412         # chase all nodes comprising this scenario,
     413         # marking them for retention.
     414         for node in scenario._node_list:
     415            node.retain = True
     416
     417      # scan for any non-retained scenarios and tree nodes.
     418      scenarios_to_delete = []
     419      tree_nodes_to_delete = []
     420      for scenario in self._scenarios:
     421         if hasattr(scenario, "retain") is True:
     422            delattr(scenario, "retain")
     423            pass
     424         else:
     425            scenarios_to_delete.append(scenario)             
     426            del self._scenario_map[scenario._name]
     427
     428      for tree_node in self._tree_nodes:
     429         if hasattr(tree_node, "retain") is True:
     430            delattr(tree_node, "retain")
     431            pass
     432         else:
     433            tree_nodes_to_delete.append(tree_node)
     434            del self._tree_node_map[tree_node._name]
     435
     436      # JPW does not claim the following routines are
     437      # the most efficient. rather, they get the job
     438      # done while avoiding serious issues with
     439      # attempting to remove elements from a list that
     440      # you are iterating over.
     441
     442      # delete all references to unmarked scenarios
     443      # and child tree nodes in the scenario tree node
     444      # structures.
     445      for tree_node in self._tree_nodes:
     446         for scenario in scenarios_to_delete:
     447            if scenario in tree_node._scenarios:
     448               tree_node._scenarios.remove(scenario)
     449         for node_to_delete in tree_nodes_to_delete:
     450            if node_to_delete in tree_node._children:
     451               tree_node._children.remove(node_to_delete)
     452
     453      # delete all references to unmarked tree nodes
     454      # in the scenario tree stage structures.
     455      for stage in self._stages:
     456         for tree_node in tree_nodes_to_delete:
     457            if tree_node in stage._tree_nodes:
     458               stage._tree_nodes.remove(tree_node)
     459
     460      # delete all unreferenced entries from the core scenario
     461      # tree data structures.
     462      for scenario in scenarios_to_delete:
     463         self._scenarios.remove(scenario)
     464      for tree_node in tree_nodes_to_delete:
     465         self._tree_nodes.remove(tree_node)
     466
    384467   #
    385468   # returns the root node of the scenario tree
Note: See TracChangeset for help on using the changeset viewer.