Changeset 2131


Ignore:
Timestamp:
Jan 4, 2010 6:21:42 PM (11 years ago)
Author:
jwatson
Message:

Various fixes in PH due to clean-up of Var and Param "None"-based access to singleton instances.

Added post-instance-creation callback in PH extensions to support CVaR.

Location:
coopr.pysp/trunk/coopr/pysp
Files:
3 edited

Legend:

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

    r2127 r2131  
    437437            new_w_index = reference_variable._index
    438438            new_w_parameter_name = "PHWEIGHT_"+reference_variable.name
    439             new_w_parameter = Param(new_w_index,name=new_w_parameter_name)
     439            # this bit of ugliness is due to Pyomo not correctly handling the Param construction
     440            # case when the supplied index set consists strictly of None, i.e., the source variable
     441            # is a singleton. this case be cleaned up when the source issue in Pyomo is fixed.
     442            new_w_parameter = None
     443            if (len(new_w_index) is 1) and (None in new_w_index):
     444               new_w_parameter = Param(name=new_w_parameter_name)
     445            else:
     446               new_w_parameter = Param(new_w_index,name=new_w_parameter_name)
    440447            setattr(instance,new_w_parameter_name,new_w_parameter)
    441448
     
    443450            # the parameter that hasn't been explicitly assigned, you just get the default value as a constant. I'm not
    444451            # sure if this has to do with the model output, or the function of the model, but I'm doing this to avoid the
    445             # issue in any case for now.
     452            # issue in any case for now. NOTE: I'm not sure this is still the case in Pyomo.
    446453            for index in new_w_index:
    447454               new_w_parameter[index] = 0.0
     
    451458            new_avg_index = reference_variable._index
    452459            new_avg_parameter_name = "PHAVG_"+reference_variable.name
    453             new_avg_parameter = Param(new_avg_index,name=new_avg_parameter_name)
     460            new_avg_parameter = None
     461            if (len(new_avg_index) is 1) and (None in new_avg_index):
     462               new_avg_parameter = Param(name=new_avg_parameter_name)
     463            else:
     464               new_avg_parameter = Param(new_avg_index,name=new_avg_parameter_name)
    454465            setattr(instance,new_avg_parameter_name,new_avg_parameter)
    455466
     
    461472            new_rho_index = reference_variable._index
    462473            new_rho_parameter_name = "PHRHO_"+reference_variable.name
    463             new_rho_parameter = Param(new_rho_index,name=new_rho_parameter_name)
     474            new_rho_parameter = None
     475            if (len(new_avg_index) is 1) and (None in new_avg_index):
     476               new_rho_parameter = Param(name=new_rho_parameter_name)
     477            else:
     478               new_rho_parameter = Param(new_rho_index,name=new_rho_parameter_name)
    464479            setattr(instance,new_rho_parameter_name,new_rho_parameter)
    465480
     
    474489               new_penalty_term_variable_name = "PHQUADPENALTY_"+reference_variable.name
    475490               # this is a quadratic penalty term - the lower bound is 0!
    476                new_penalty_term_variable = Var(new_penalty_term_variable_index, name=new_penalty_term_variable_name, bounds=(0.0,None))
     491               new_penalty_term_variable = None
     492               if (len(new_avg_index) is 1) and (None in new_avg_index):
     493                  new_penalty_term_variable = Var(name=new_penalty_term_variable_name, bounds=(0.0,None))                 
     494               else:
     495                  new_penalty_term_variable = Var(new_penalty_term_variable_index, name=new_penalty_term_variable_name, bounds=(0.0,None))
    477496               new_penalty_term_variable.construct()
    478497               setattr(instance, new_penalty_term_variable_name, new_penalty_term_variable)
     
    485504            new_blend_index = reference_variable._index
    486505            new_blend_parameter_name = "PHBLEND_"+reference_variable.name
    487             new_blend_parameter = Param(new_blend_index, name=new_blend_parameter_name, within=Binary)
     506            new_blend_parameter = None
     507            if (len(new_avg_index) is 1) and (None in new_avg_index):
     508               new_blend_parameter = Param(name=new_blend_parameter_name, within=Binary)
     509            else:
     510               new_blend_parameter = Param(new_blend_index, name=new_blend_parameter_name, within=Binary)
    488511            setattr(instance,new_blend_parameter_name,new_blend_parameter)
    489512
     
    797820         self._instance_augmented_attributes[scenario._name] = []
    798821
     822      # let plugins know if they care - this callback point allows
     823      # users to create/modify the original scenario instances and/or
     824      # the scenario tree prior to creating PH-related parameters,
     825      # variables, and the like.
     826      for plugin in self._ph_plugins:     
     827         plugin.post_instance_creation(self)         
     828
    799829      # create ph-specific parameters (weights, xbar, etc.) for each instance.
    800830
     
    839869               new_min_index = reference_variable._index
    840870               new_min_parameter_name = "NODEMIN_"+reference_variable.name
    841                new_min_parameter = Param(new_min_index,name=new_min_parameter_name)
     871               # this bit of ugliness is due to Pyomo not correctly handling the Param construction
     872               # case when the supplied index set consists strictly of None, i.e., the source variable
     873               # is a singleton. this case be cleaned up when the source issue in Pyomo is fixed.
     874               new_min_parameter = None
     875               if (len(new_min_index) is 1) and (None in new_min_index):
     876                  new_min_parameter = Param(name=new_min_parameter_name)
     877               else:
     878                  new_min_parameter = Param(new_min_index,name=new_min_parameter_name)
    842879               for index in new_min_index:
    843880                  new_min_parameter[index] = 0.0
     
    846883               new_avg_index = reference_variable._index
    847884               new_avg_parameter_name = "NODEAVG_"+reference_variable.name
    848                new_avg_parameter = Param(new_avg_index,name=new_avg_parameter_name)
     885               new_avg_parameter = None
     886               if (len(new_avg_index) is 1) and (None in new_avg_index):
     887                  new_avg_parameter = Param(name=new_avg_parameter_name)
     888               else:
     889                  new_avg_parameter = Param(new_avg_index,name=new_avg_parameter_name)
    849890               for index in new_avg_index:
    850                   new_avg_parameter[index] = 0.0
     891                  new_avg_parameter[index] = 0.0                     
    851892               tree_node._averages[reference_variable.name] = new_avg_parameter
    852893
    853894               new_max_index = reference_variable._index
    854895               new_max_parameter_name = "NODEMAX_"+reference_variable.name
    855                new_max_parameter = Param(new_max_index,name=new_max_parameter_name)
     896               new_max_parameter = None
     897               if (len(new_max_index) is 1) and (None in new_max_index):
     898                  new_max_parameter = Param(name=new_max_parameter_name)
     899               else:
     900                  new_max_parameter = Param(new_max_index,name=new_max_parameter_name)
    856901               for index in new_max_index:
    857                   new_max_parameter[index] = 0.0
     902                  new_max_parameter[index] = 0.0                     
    858903               tree_node._maximums[reference_variable.name] = new_max_parameter
    859904
     
    928973         #       piecewise linear function. otherwise, the newly introduced variables won't be flagged
    929974         #       as unused (as is correct for iteration 0), and the output writer will crater.
    930          if self._linearize_nonbinary_penalty_terms > 0:
    931            instance.presolve()           
     975         # IMPT: I decided to presolve unconditionally, as PH extensions can add arbitrary components
     976         #       to the base scenario instances - and the variable values/etc. need to be collectged.
     977         instance.presolve()
    932978           
    933979         # there's nothing to warm-start from in iteration 0, so don't include the keyword in the solve call.
     
    10291075                  if is_used is True:
    10301076
    1031                      if index is None:
    1032                         tree_node._minimums[variable.name].value = min
    1033                         tree_node._averages[variable.name].value = avg / node_probability
    1034                         tree_node._maximums[variable.name].value = max                                               
    1035                      else:
    1036                         tree_node._minimums[variable.name][index] = min
    1037                         tree_node._averages[variable.name][index] = avg / node_probability
    1038                         tree_node._maximums[variable.name][index] = max                       
     1077                     tree_node._minimums[variable.name][index] = min
     1078                     tree_node._averages[variable.name][index] = avg / node_probability
     1079                     tree_node._maximums[variable.name][index] = max                       
    10391080
    10401081                     # distribute the newly computed average to the xbar variable in
     
    10441085                        instance = self._instances[scenario._name]
    10451086                        avg_parameter = getattr(instance, avg_parameter_name)
    1046                         if index is None:
    1047                            avg_parameter.value = avg / node_probability
    1048                         else:
    1049                            avg_parameter[index] = avg / node_probability
     1087                        avg_parameter[index] = avg / node_probability
    10501088
    10511089      end_time = time.time()
  • coopr.pysp/trunk/coopr/pysp/testphextension.py

    r2127 r2131  
    1515
    1616    implements (phextension.IPHExtension)
     17
     18    def post_instance_creation(self, ph):
     19        """ Called after PH initialization has created the scenario instances, but before any PH-related weights/variables/parameters/etc are defined!"""
     20        print "POST INSTANCE CREATION PH CALLBACK INVOKED"   
    1721
    1822    def post_ph_initialization(self, ph):
  • coopr.pysp/trunk/coopr/pysp/wwphextension.py

    r2127 r2131  
    169169
    170170      self.slam_list.sort(slam_priority_descend_compare)
     171
     172#==================================================
     173   def post_instance_creation(self, ph):
     174       """ Called after PH initialization has created the scenario instances, but before any PH-related weights/variables/parameters/etc are defined!"""
     175       # we don't muck with the instances.
     176       pass
    171177
    172178#==================================================
Note: See TracChangeset for help on using the changeset viewer.