Changeset 1890


Ignore:
Timestamp:
Nov 14, 2009 7:08:09 PM (12 years ago)
Author:
jwatson
Message:

Added option to PH to fix all discrete variables that are converged upon termination. Functionality is within the WW PH extension. Not for typical use, but useful for debugging.

Location:
coopr.pysp/trunk
Files:
2 added
2 edited

Legend:

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

    r1858 r1890  
    12511251            print "Halting PH - reached maximal iteration count="+str(self._max_iterations)
    12521252
     1253      if self._verbose is True:
     1254         print "Number of discrete variables fixed before final plugin calls="+str(self._total_fixed_discrete_vars)+" (total="+str(self._total_discrete_vars)+")"
     1255         print "Number of continuous variables fixed before final plugin calls="+str(self._total_fixed_continuous_vars)+" (total="+str(self._total_continuous_vars)+")"           
     1256
     1257      # let plugins know if they care. do this before
     1258      # the final solution / statistics output, as the plugins
     1259      # might do some final tweaking.
     1260      for plugin in self._ph_plugins:
     1261         plugin.post_ph_execution(self)
     1262
     1263      # update the fixed variable statistics - the plugins might have done something.
     1264      (self._total_fixed_discrete_vars,self._total_fixed_continuous_vars) = self.compute_fixed_variable_counts()                       
     1265
    12531266      print "PH complete"
    12541267
    1255       if self._verbose is True:
    1256          print "Convergence history:"
    1257          self._converger.pprint()
     1268      print "Convergence history:"
     1269      self._converger.pprint()
     1270
     1271      print "Final number of discrete variables fixed="+str(self._total_fixed_discrete_vars)+" (total="+str(self._total_discrete_vars)+")"
     1272      print "Final number of continuous variables fixed="+str(self._total_fixed_continuous_vars)+" (total="+str(self._total_continuous_vars)+")"         
    12581273
    12591274      print "Final variable values:"
     
    12721287      # things like rhos, etc), but we do clean up constraints, as that really hoses up the ef writer.
    12731288      self._cleanup_scenario_instances()
    1274 
    1275       # let plugins know if they care.
    1276       for plugin in self._ph_plugins:
    1277          plugin.post_ph_execution(self)                                 
    12781289
    12791290   #
  • coopr.pysp/trunk/coopr/pysp/wwphextension.py

    r1855 r1890  
    4242      self._configuration_filename = None
    4343      self._suffix_filename = None
    44 
    4544
    4645#=========================
     
    180179      # we always track convergence of continuous variables, but we may not want to fix/slam them.                                                           
    181180      self.fix_continuous_variables = False
     181
     182      # there are occasions where we might want to fix any values at the end of the
     183      # run if the scenarios agree - even if the normal fixing criterion (e.g.,
     184      # converged for N iterations) don't apply. one example is when the term-diff
     185      # is 0, at which point you really do have a solution. currently only applies
     186      # to discrete variables.
     187      self.fix_discrete_variables_at_exit = False
    182188
    183189      # set up the mipgap parameters (zero means ignore)
     
    531537   def post_ph_execution(self, ph):
    532538
    533        pass         
     539      if self.fix_discrete_variables_at_exit is True:
     540         print "WW PH extension: Fixing all discrete variables that are converged at termination"
     541         self._fix_all_converged_discrete_variables(ph)
    534542
    535543#=========================
     
    760768         
    761769      print "Warning: Nothing free with a non-zero slam priority - no variable will be slammed"
     770
     771#==========================
     772# a simple utility to fix any discrete variables to their common value, assuming they
     773# are at a common value
     774#==========================
     775
     776   def _fix_all_converged_discrete_variables(self, ph):
     777
     778      num_variables_fixed = 0
     779
     780      for stage in ph._scenario_tree._stages[:-1]: # no blending over the final stage
     781         
     782         for tree_node in stage._tree_nodes:
     783
     784            for (variable, index_template, variable_indices) in stage._variables:
     785
     786               variable_name = variable.name
     787               variable_type = variable.domain
     788
     789               for index in variable_indices:
     790
     791                  # determine if this index is used - otherwise, don't waste time
     792                  # fixing and cycle checking. for one, the code will crash :-) with
     793                  # None values during the cycle checking computation!
     794
     795                  is_used = True # until proven otherwise                     
     796                  for scenario in tree_node._scenarios:
     797                     instance = ph._instances[scenario._name]
     798                     if getattr(instance,variable_name)[index].status == VarStatus.unused:
     799                        is_used = False
     800
     801                  if is_used is True:                       
     802
     803                     # determine if the variable is already fixed.
     804                     instance_fixed_count = 0
     805                     for scenario in tree_node._scenarios:
     806                        instance = ph._instances[scenario._name]
     807                        if getattr(instance,variable_name)[index].fixed is True:
     808                           instance_fixed_count += 1
     809                     if ((instance_fixed_count > 0) and (instance_fixed_count < len(tree_node._scenarios))):
     810                        raise RuntimeError, "Variable="+variable_name+str(index)+" is fixed in "+str(instance_fixed_count)+" scenarios, but less than the number of scenarios at tree node="+tree_node._name
     811
     812                     if instance_fixed_count == 0:
     813
     814                        if isinstance(variable_type, IntegerSet) or isinstance(variable_type, BooleanSet):                           
     815                           node_min = self.Int_If_Close_Enough(ph, tree_node._minimums[variable_name][index]())
     816                           node_max = self.Int_If_Close_Enough(ph, tree_node._maximums[variable_name][index]())
     817
     818                           if node_min == node_max:
     819                              self._fix_var(ph, tree_node, variable, index, node_min)
     820                              num_variables_fixed = num_variables_fixed + 1
     821
     822      print "Total number of variables fixed at PH termination due to convergence="+str(num_variables_fixed)
Note: See TracChangeset for help on using the changeset viewer.