Changeset 3220


Ignore:
Timestamp:
Nov 5, 2010 10:28:29 PM (10 years ago)
Author:
jwatson
Message:

Various fixes to the WW PH extension, bringing it in compliance to previous commit changes.

File:
1 edited

Legend:

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

    r3073 r3220  
    247247
    248248      # set up tree storage for statistics that we care about tracking.
    249       for stage in ph._scenario_tree._stages:
    250 
    251          if stage != ph._scenario_tree._stages[-1]:
    252 
    253             # first, gather all unique variables referenced in self stage
    254             # self "gather" step is currently required because we're being lazy
    255             # in terms of index management in the scenario tree
    256 ##            stage_variables = {}
    257 ##            for (reference_variable, index_template, reference_index) in stage._variables:
    258 ##               if reference_variable.name not in stage_variables.keys():
    259 ##                  stage_variables[reference_variable.name] = reference_variable
     249      for stage in ph._scenario_tree._stages[:-1]:
     250
     251         # first, gather all unique variables referenced in self stage
     252         # self "gather" step is currently required because we're being lazy
     253         # in terms of index management in the scenario tree
     254##         stage_variables = {}
     255##         for (reference_variable, index_template, reference_index) in stage._variables:
     256##            if reference_variable.name not in stage_variables.keys():
     257##               stage_variables[reference_variable.name] = reference_variable
    260258##
    261             for tree_node in stage._tree_nodes:
    262                tree_node._num_iters_converged = {}
    263                tree_node._last_converged_val = {}
    264                tree_node._w_hash = {}
    265                tree_node._fixed_var_flag = {}
    266 
    267                for (variable, index_template, variable_indices) in stage._variables:
    268 
    269                   variable_name = variable.name
    270                   variable_type = variable.domain
    271 
    272                   # create the parameters for all indices, even though this might be a bit
    273                   # wasteful. in practice, this probably won't be the case, and determining
    274                   # the reduced index set would probably take longer that it is worth.
    275 
    276                   new_stat_index = variable._index
    277                   new_stat_parameter_name = "NODESTAT_NUM_ITERS_CONVERGED_"+variable.name
    278                   new_stat_parameter = None
    279                   # this bit of ugliness is due to Pyomo not correctly handling the Param construction
    280                   # case when the supplied index set consists strictly of None, i.e., the source variable
    281                   # is a singleton. this case be cleaned up when the source issue in Pyomo is fixed.                     
    282                   if (len(new_stat_index) is 1) and (None in new_stat_index):
    283                      new_stat_parameter = Param(name=new_stat_parameter_name, mutable=True)
    284                   else:
    285                      new_stat_parameter = Param(new_stat_index, name=new_stat_parameter_name, mutable=True)
    286                   for newindex in new_stat_index:
    287                      new_stat_parameter[newindex] = 0
    288                   tree_node._num_iters_converged[variable.name] = new_stat_parameter
     259         for tree_node in stage._tree_nodes:
     260               
     261            tree_node._num_iters_converged = {}
     262            tree_node._last_converged_val = {}
     263            tree_node._w_hash = {}
     264            tree_node._fixed_var_flag = {}
     265
     266            for (reference_variable, index_template) in stage._variables:
     267
     268               variable_name = reference_variable.name
     269               variable_type = reference_variable.domain
     270
     271               variable_indices = tree_node._variable_indices[variable_name]
     272
     273               new_param_index = getattr(ph._instances[tree_node._scenarios[0]._name], variable_name)._index
     274
     275               # create the parameters for all indices, even though this might be a bit
     276               # wasteful. in practice, this probably won't be the case, and determining
     277               # the reduced index set would probably take longer that it is worth.
     278
     279               new_stat_index = new_param_index
     280               new_stat_parameter_name = "NODESTAT_NUM_ITERS_CONVERGED_"+reference_variable.name
     281               new_stat_parameter = None
     282               # this bit of ugliness is due to Pyomo not correctly handling the Param construction
     283               # case when the supplied index set consists strictly of None, i.e., the source variable
     284               # is a singleton. this case be cleaned up when the source issue in Pyomo is fixed.                     
     285               if (len(new_stat_index) is 1) and (None in new_stat_index):
     286                  new_stat_parameter = Param(name=new_stat_parameter_name, mutable=True)
     287               else:
     288                  new_stat_parameter = Param(new_stat_index, name=new_stat_parameter_name, mutable=True)
     289               for newindex in new_stat_index:
     290                  new_stat_parameter[newindex] = 0
     291               tree_node._num_iters_converged[reference_variable.name] = new_stat_parameter
    289292                     
    290                   # need to know to what we have most recently converged
    291                   new_conv_index = variable._index
    292                   new_conv_parameter_name = "NODESTAT_LAST_CONVERGED_VAL_"+variable.name
    293                   new_conv_parameter = None
    294                   if (len(new_conv_index) is 1) and (None in new_conv_index):
    295                      new_conv_parameter = Param(name=new_conv_parameter_name, mutable=True)
    296                   else:
    297                      new_conv_parameter = Param(new_conv_index, name=new_conv_parameter_name, mutable=True)
    298                   for newindex in new_conv_index:
    299                      new_conv_parameter[newindex] = 0.5 # not an int, so harmless
    300                   tree_node._last_converged_val[variable.name] = new_conv_parameter
     293               # need to know to what we have most recently converged
     294               new_conv_index = new_param_index
     295               new_conv_parameter_name = "NODESTAT_LAST_CONVERGED_VAL_"+reference_variable.name
     296               new_conv_parameter = None
     297               if (len(new_conv_index) is 1) and (None in new_conv_index):
     298                  new_conv_parameter = Param(name=new_conv_parameter_name, mutable=True)
     299               else:
     300                  new_conv_parameter = Param(new_conv_index, name=new_conv_parameter_name, mutable=True)
     301               for newindex in new_conv_index:
     302                  new_conv_parameter[newindex] = 0.5 # not an int, so harmless
     303               tree_node._last_converged_val[reference_variable.name] = new_conv_parameter
    301304                     
    302                   # need to know to what has been fixed
    303                   new_fix_index = variable._index
    304                   new_fix_parameter_name = "NODESTAT_FIXED_FLAG_VAL_"+variable.name
    305                   new_fix_parameter = None
    306                   if (len(new_fix_index) is 1) and (None in new_fix_index):
    307                      new_fix_parameter = Param(name=new_fix_parameter_name, mutable=True)
    308                   else:
    309                      new_fix_parameter = Param(new_fix_index, name=new_fix_parameter_name, mutable=True)
    310                   for newindex in new_fix_index:
    311                      new_fix_parameter[newindex] = False
    312                   tree_node._fixed_var_flag[variable.name] = new_fix_parameter
    313 
    314                   # now make the w hash value storage array
    315                   new_hash_index = variable._index
    316                   new_hash_parameter_name = "W_HASH_STORAGE_"+variable.name
    317                   new_hash_parameter = None
    318                   if (len(new_hash_index) is 1) and (None in new_hash_index):
    319                      new_hash_parameter = Param(ph._iteration_index_set, name=new_hash_parameter_name, mutable=True)
    320                   else:
    321                      new_hash_parameter = Param(new_hash_index, ph._iteration_index_set, name=new_hash_parameter_name, mutable=True)
    322                   for newindex in new_hash_index:
    323                      for i in range(0, ph._max_iterations+1):
    324                         # the following if-then block is a complete hack, due to the
    325                         # fact that we can't index by None if the Param is unary.
    326                         if new_hash_parameter.dim() == 1:
    327                            new_hash_parameter[i] = 0
    328                         else:
    329                            new_hash_parameter[newindex,i] = 0
    330                   tree_node._w_hash[variable.name] = new_hash_parameter
     305               # need to know to what has been fixed
     306               new_fix_index = new_param_index
     307               new_fix_parameter_name = "NODESTAT_FIXED_FLAG_VAL_"+reference_variable.name
     308               new_fix_parameter = None
     309               if (len(new_fix_index) is 1) and (None in new_fix_index):
     310                  new_fix_parameter = Param(name=new_fix_parameter_name, mutable=True)
     311               else:
     312                  new_fix_parameter = Param(new_fix_index, name=new_fix_parameter_name, mutable=True)
     313               for newindex in new_fix_index:
     314                  new_fix_parameter[newindex] = False
     315               tree_node._fixed_var_flag[reference_variable.name] = new_fix_parameter
     316
     317               # now make the w hash value storage array
     318               new_hash_index = new_param_index
     319               new_hash_parameter_name = "W_HASH_STORAGE_"+reference_variable.name
     320               new_hash_parameter = None
     321               if (len(new_hash_index) is 1) and (None in new_hash_index):
     322                  new_hash_parameter = Param(ph._iteration_index_set, name=new_hash_parameter_name, mutable=True)
     323               else:
     324                  new_hash_parameter = Param(new_hash_index, ph._iteration_index_set, name=new_hash_parameter_name, mutable=True)
     325               for newindex in new_hash_index:
     326                  for i in range(0, ph._max_iterations+1):
     327                     # the following if-then block is a complete hack, due to the
     328                     # fact that we can't index by None if the Param is unary.
     329                     if new_hash_parameter.dim() == 1:
     330                        new_hash_parameter[i] = 0
     331                     else:
     332                        new_hash_parameter[newindex,i] = 0
     333               tree_node._w_hash[reference_variable.name] = new_hash_parameter
    331334                 
    332                   # JPW has no idea why the following code block is here, or if it is necessary.
    333                   for index in variable_indices:
    334 
    335                      # IMPT: it has bitten us before in this plug-in, so I'll state the obvious:
    336                      #       variable values in the last stage of a stochastic program will *not*
    337                      #       have a defined _stage attribute.
    338                      variable[index]._stage = stage
     335               # JPW has no idea why the following code block is here, or if it is necessary.
     336               for index in variable_indices:
     337
     338                  # IMPT: it has bitten us before in this plug-in, so I'll state the obvious:
     339                  #       variable values in the last stage of a stochastic program will *not*
     340                  #       have a defined _stage attribute.
     341                  # NOTE: the use of the reference variable here, in contrast to a instance-specific
     342                  #       variable, is potentially dangerous.
     343                  reference_variable[index]._stage = stage
    339344
    340345
     
    362367   def post_iteration_0_solves(self, ph):
    363368
    364       for stage in ph._scenario_tree._stages:
     369      for stage in ph._scenario_tree._stages[:-1]:
    365370         
    366          if stage != ph._scenario_tree._stages[-1]: # no blending over the final stage
    367            
    368             for tree_node in stage._tree_nodes:
    369 
    370                for (variable, index_template, variable_indices) in stage._variables:
     371         for tree_node in stage._tree_nodes:
     372
     373            for (variable, index_template) in stage._variables:
    371374                 
    372                   variable_name = variable.name
    373                   variable_type = variable.domain
    374 
    375                   for index in variable_indices:
    376 
    377                      # determine if this index is used - otherwise, don't waste time
    378                      # fixing and cycle checking. for one, the code will crash :-) with
    379                      # none values during the cycle checking computation!
    380 
    381                      is_used = True # until proven otherwise                     
     375               variable_name = variable.name
     376               variable_type = variable.domain
     377
     378               variable_indices = tree_node._variable_indices[variable_name]
     379
     380               for index in variable_indices:
     381
     382                  # determine if this index is used - otherwise, don't waste time
     383                  # fixing and cycle checking. for one, the code will crash :-) with
     384                  # none values during the cycle checking computation!
     385
     386                  is_used = True # until proven otherwise                     
     387                  for scenario in tree_node._scenarios:
     388                     instance = ph._instances[scenario._name]
     389                     if getattr(instance,variable_name)[index].status == VarStatus.unused:
     390                        is_used = False
     391
     392                  if is_used is True:
     393
     394                     # unlikely, but variables might be fixed even at this stage, depending on
     395                     # what weirdness users do prior to the iteration 0 solves.
     396                     instance_fixed_count = 0
    382397                     for scenario in tree_node._scenarios:
    383398                        instance = ph._instances[scenario._name]
    384                         if getattr(instance,variable_name)[index].status == VarStatus.unused:
    385                            is_used = False
    386 
    387                      if is_used is True:
    388 
    389                         # unlikely, but variables might be fixed even at this stage, depending on
    390                         # what weirdness users do prior to the iteration 0 solves.
    391                         instance_fixed_count = 0
    392                         for scenario in tree_node._scenarios:
    393                            instance = ph._instances[scenario._name]
    394                            if getattr(instance,variable_name)[index].fixed is True:
    395                               instance_fixed_count += 1
    396                         if ((instance_fixed_count > 0) and (instance_fixed_count < len(tree_node._scenarios))):
    397                            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
    398 
    399                         if instance_fixed_count == 0:
    400 
    401                            if isinstance(variable_type, IntegerSet) or isinstance(variable_type, BooleanSet):                           
    402                               node_min = self.Int_If_Close_Enough(ph, value(tree_node._minimums[variable_name][index]))
    403                               node_max = self.Int_If_Close_Enough(ph, value(tree_node._maximums[variable_name][index]))
    404 
    405                               # update convergence prior to checking for fixing.
    406                               self._int_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
    407                               attrvariable = ph._model_instance.active_components(Var)[variable_name][index]
    408                               if hasattr(attrvariable, 'Iter0FixIfConvergedAtLB'):
    409                                  lb = getattr(attrvariable, 'Iter0FixIfConvergedAtLB')
    410                               else:
    411                                  lb = self.Iter0FixIfConvergedAtLB
    412                               if hasattr(attrvariable, 'Iter0FixIfConvergedatUB'):
    413                                  ub = getattr(attrvariable, 'Iter0FixIfConvergedAtUB')
    414                               else:
    415                                  ub = self.Iter0FixIfConvergedAtUB
    416                               if hasattr(attrvariable, 'Iter0FixIfConvergedAtNB'):
    417                                  nb = getattr(attrvariable, 'Iter0FixIfConvergedAtNB')
    418                               else:
    419                                  nb = self.Iter0FixIfConvergedAtNB
    420                               if self._should_fix_discrete_due_to_conv(tree_node, variable, index, lb, ub, nb):
    421                                  self._fix_var(ph, tree_node, variable, index, node_min)
    422                               elif self.W_hash_history_len > 0:   # if not fixed, then hash - no slamming at iteration 0
    423                                  self._w_hash_acct(ph, tree_node, variable_name, index) # obviously not checking for cycles at iteration 0!
    424 
     399                        if getattr(instance,variable_name)[index].fixed is True:
     400                           instance_fixed_count += 1
     401                     if ((instance_fixed_count > 0) and (instance_fixed_count < len(tree_node._scenarios))):
     402                        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
     403
     404                     if instance_fixed_count == 0:
     405
     406                        if isinstance(variable_type, IntegerSet) or isinstance(variable_type, BooleanSet):                           
     407                           node_min = self.Int_If_Close_Enough(ph, value(tree_node._minimums[variable_name][index]))
     408                           node_max = self.Int_If_Close_Enough(ph, value(tree_node._maximums[variable_name][index]))
     409
     410                           # update convergence prior to checking for fixing.
     411                           self._int_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
     412                           attrvariable = ph._model_instance.active_components(Var)[variable_name][index]
     413                           if hasattr(attrvariable, 'Iter0FixIfConvergedAtLB'):
     414                              lb = getattr(attrvariable, 'Iter0FixIfConvergedAtLB')
    425415                           else:
     416                              lb = self.Iter0FixIfConvergedAtLB
     417                           if hasattr(attrvariable, 'Iter0FixIfConvergedatUB'):
     418                              ub = getattr(attrvariable, 'Iter0FixIfConvergedAtUB')
     419                           else:
     420                              ub = self.Iter0FixIfConvergedAtUB
     421                           if hasattr(attrvariable, 'Iter0FixIfConvergedAtNB'):
     422                              nb = getattr(attrvariable, 'Iter0FixIfConvergedAtNB')
     423                           else:
     424                              nb = self.Iter0FixIfConvergedAtNB
     425                           if self._should_fix_discrete_due_to_conv(tree_node, variable, index, lb, ub, nb):
     426                              self._fix_var(ph, tree_node, variable, index, node_min)
     427                           elif self.W_hash_history_len > 0:   # if not fixed, then hash - no slamming at iteration 0
     428                              self._w_hash_acct(ph, tree_node, variable_name, index) # obviously not checking for cycles at iteration 0!
     429
     430                        else:
    426431                             
    427                               node_min = value(tree_node._minimums[variable_name][index])
    428                               node_max = value(tree_node._maximums[variable_name][index])
     432                           node_min = value(tree_node._minimums[variable_name][index])
     433                           node_max = value(tree_node._maximums[variable_name][index])
    429434                             
    430                               self._continuous_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
     435                           self._continuous_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
    431436                             
    432437# jpw: not sure if we care about cycle detection in continuous variables?
    433 #                              if self.W_hash_history_len > 0: 
    434 #                                 self._w_hash_acct(ph, tree_node, variable_name, index)
     438#                           if self.W_hash_history_len > 0: 
     439#                              self._w_hash_acct(ph, tree_node, variable_name, index)
    435440                             
    436441
     
    455460   def post_iteration_k_solves(self, ph):
    456461
    457       for stage in ph._scenario_tree._stages:
     462      for stage in ph._scenario_tree._stages[:-1]:
    458463         
    459          if stage != ph._scenario_tree._stages[-1]: # no blending over the final stage
    460            
    461             for tree_node in stage._tree_nodes:
    462 
    463                for (variable, index_template, variable_indices) in stage._variables:
    464 
    465                   variable_name = variable.name
    466                   variable_type = variable.domain
    467 
    468                   for index in variable_indices:
    469 
    470                      # determine if this index is used - otherwise, don't waste time
    471                      # fixing and cycle checking. for one, the code will crash :-) with
    472                      # None values during the cycle checking computation!
    473 
    474                      is_used = True # until proven otherwise                     
     464         for tree_node in stage._tree_nodes:
     465
     466            for (variable, index_template) in stage._variables:
     467
     468               variable_name = variable.name
     469               variable_type = variable.domain
     470
     471               variable_indices = tree_node._variable_indices[variable_name]
     472
     473               for index in variable_indices:
     474
     475                  # determine if this index is used - otherwise, don't waste time
     476                  # fixing and cycle checking. for one, the code will crash :-) with
     477                  # None values during the cycle checking computation!
     478
     479                  is_used = True # until proven otherwise                     
     480                  for scenario in tree_node._scenarios:
     481                     instance = ph._instances[scenario._name]
     482                     if getattr(instance,variable_name)[index].status == VarStatus.unused:
     483                        is_used = False
     484
     485                  if is_used is True:                       
     486
     487                     # determine if the variable is already fixed.
     488                     instance_fixed_count = 0
    475489                     for scenario in tree_node._scenarios:
    476490                        instance = ph._instances[scenario._name]
    477                         if getattr(instance,variable_name)[index].status == VarStatus.unused:
    478                            is_used = False
    479 
    480                      if is_used is True:                       
    481 
    482                         # determine if the variable is already fixed.
    483                         instance_fixed_count = 0
    484                         for scenario in tree_node._scenarios:
    485                            instance = ph._instances[scenario._name]
    486                            if getattr(instance,variable_name)[index].fixed is True:
    487                               instance_fixed_count += 1
    488                         if ((instance_fixed_count > 0) and (instance_fixed_count < len(tree_node._scenarios))):
    489                            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
    490 
    491                         if instance_fixed_count == 0:
    492 
    493                            if isinstance(variable_type, IntegerSet) or isinstance(variable_type, BooleanSet):                           
    494                               node_min = self.Int_If_Close_Enough(ph, value(tree_node._minimums[variable_name][index]))
    495                               node_max = self.Int_If_Close_Enough(ph, value(tree_node._maximums[variable_name][index]))
    496 
    497                               # update convergence prior to checking for fixing.
    498                               self._int_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
    499 
    500                               # now check on permissions to converge to various placed (e.g., lb is lb permission)
    501                               attrvariable = ph._model_instance.active_components(Var)[variable_name][index]
    502                               if hasattr(attrvariable, 'FixWhenItersConvergedAtLB'):
    503                                  lb = getattr(attrvariable, 'FixWhenItersConvergedAtLB')
    504                               else:
    505                                  lb = self.FixWhenItersConvergedAtLB
    506                               if hasattr(attrvariable, 'FixWhenItersConvergedAtUB'):
    507                                  ub = getattr(attrvariable, 'FixWhenItersConvergedAtUB')
    508                               else:
    509                                  ub = self.FixWhenItersConvergedAtUB
    510                               if hasattr(attrvariable, 'FixWhenItersConvergedAtNB'):
    511                                  nb = getattr(attrvariable, 'FixWhenItersConvergedAtNB')
    512                               else:
    513                                  nb = self.FixWhenItersConvergedAtNB
     491                        if getattr(instance,variable_name)[index].fixed is True:
     492                           instance_fixed_count += 1
     493                     if ((instance_fixed_count > 0) and (instance_fixed_count < len(tree_node._scenarios))):
     494                        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
     495
     496                     if instance_fixed_count == 0:
     497
     498                        if isinstance(variable_type, IntegerSet) or isinstance(variable_type, BooleanSet):                           
     499                           node_min = self.Int_If_Close_Enough(ph, value(tree_node._minimums[variable_name][index]))
     500                           node_max = self.Int_If_Close_Enough(ph, value(tree_node._maximums[variable_name][index]))
     501
     502                           # update convergence prior to checking for fixing.
     503                           self._int_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
     504
     505                           # now check on permissions to converge to various placed (e.g., lb is lb permission)
     506                           attrvariable = ph._model_instance.active_components(Var)[variable_name][index]
     507                           if hasattr(attrvariable, 'FixWhenItersConvergedAtLB'):
     508                              lb = getattr(attrvariable, 'FixWhenItersConvergedAtLB')
     509                           else:
     510                              lb = self.FixWhenItersConvergedAtLB
     511                           if hasattr(attrvariable, 'FixWhenItersConvergedAtUB'):
     512                              ub = getattr(attrvariable, 'FixWhenItersConvergedAtUB')
     513                           else:
     514                              ub = self.FixWhenItersConvergedAtUB
     515                           if hasattr(attrvariable, 'FixWhenItersConvergedAtNB'):
     516                              nb = getattr(attrvariable, 'FixWhenItersConvergedAtNB')
     517                           else:
     518                              nb = self.FixWhenItersConvergedAtNB
    514519                                 
    515                               if self._should_fix_discrete_due_to_conv(tree_node, variable, index, lb, ub, nb):
     520                           if self._should_fix_discrete_due_to_conv(tree_node, variable, index, lb, ub, nb):
    516521                                 
    517                                  self._fix_var(ph, tree_node, variable, index, node_min)
     522                              self._fix_var(ph, tree_node, variable, index, node_min)
    518523                                 
    519                               else: # if not fixed, then hash and slam as necessary.
     524                           else: # if not fixed, then hash and slam as necessary.
    520525                                 
    521                                  if self.W_hash_history_len > 0:   
    522                                     self._w_hash_acct(ph, tree_node, variable_name, index)
    523                                     computed_cycle_length,msg = self.hash_hit_len(ph, tree_node, variable_name, index, False)
    524                                     if (computed_cycle_length >= self.CycleLengthSlamThreshold) and ((ph._current_iteration - self._last_slam_iter) > self.PH_Iters_Between_Cycle_Slams):
    525                                        # TBD: we may not want to slam immediately - it may disappear on it's own after a few iterations, depending on what other variables do.
    526                                        # note: we are *not* slamming the offending variable, but a selected variable
    527                                        if index is None:
    528                                           print "Cycle issue detected with variable="+variable_name
    529                                        else:
    530                                           print "Cycle issue detected with variable="+variable_name+"["+str(index)+"]"
    531                                        print msg
    532                                        print "Cycle length exceeds iteration slamming threshold="+str(self.CycleLengthSlamThreshold)+"; choosing a variable to slam"
    533                                        self._pick_one_and_slam_it(ph)
    534                                     elif (computed_cycle_length > 1) and (computed_cycle_length < self.CycleLengthSlamThreshold):
    535                                        # there was a (potential) cycle, but the slam threshold wasn't reached.
    536                                        if self.ReportPotentialCycles is True:
    537                                           if index is None:
    538                                              print "Cycle issue detected with variable="+variable_name
    539                                           else:                                         
    540                                              print "Cycle issue detected with variable="+variable_name+"["+str(index)+"]"                                         
    541                                           print msg
    542                                           print "Taking no action to break cycle - length="+str(computed_cycle_length)+" does not exceed slam threshold="+str(self.CycleLengthSlamThreshold)
    543                                     elif (computed_cycle_length >= self.CycleLengthSlamThreshold) and ((ph._current_iteration - self._last_slam_iter) > self.PH_Iters_Between_Cycle_Slams):
    544                                        # we could have slammed, but we recently did and are taking a break to see if things settle down on their own.
     526                              if self.W_hash_history_len > 0:   
     527                                 self._w_hash_acct(ph, tree_node, variable_name, index)
     528                                 computed_cycle_length,msg = self.hash_hit_len(ph, tree_node, variable_name, index, False)
     529                                 if (computed_cycle_length >= self.CycleLengthSlamThreshold) and ((ph._current_iteration - self._last_slam_iter) > self.PH_Iters_Between_Cycle_Slams):
     530                                    # TBD: we may not want to slam immediately - it may disappear on it's own after a few iterations, depending on what other variables do.
     531                                    # note: we are *not* slamming the offending variable, but a selected variable
     532                                    if index is None:
     533                                       print "Cycle issue detected with variable="+variable_name
     534                                    else:
     535                                       print "Cycle issue detected with variable="+variable_name+"["+str(index)+"]"
     536                                    print msg
     537                                    print "Cycle length exceeds iteration slamming threshold="+str(self.CycleLengthSlamThreshold)+"; choosing a variable to slam"
     538                                    self._pick_one_and_slam_it(ph)
     539                                 elif (computed_cycle_length > 1) and (computed_cycle_length < self.CycleLengthSlamThreshold):
     540                                    # there was a (potential) cycle, but the slam threshold wasn't reached.
     541                                    if self.ReportPotentialCycles is True:
    545542                                       if index is None:
    546543                                          print "Cycle issue detected with variable="+variable_name
     
    548545                                          print "Cycle issue detected with variable="+variable_name+"["+str(index)+"]"                                         
    549546                                       print msg
    550                                        print "Taking no action to break cycle - length="+str(computed_cycle_length)+" does exceed slam threshold="+str(self.CycleLengthSlamThreshold)+ \
    551                                              ", but another variable was slammed within the past "+str(self.PH_Iters_Between_Cycle_Slams)+" iterations"
    552                            else:
    553 
    554                               # obviously don't round in the continuous case.
    555                               node_min = value(tree_node._minimums[variable_name][index])
    556                               node_max = value(tree_node._maximums[variable_name][index])
    557 
    558                               # update convergence prior to checking for fixing.
    559                               self._continuous_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
    560 
    561                               if self._should_fix_continuous_due_to_conv(tree_node, variable, index):
    562                                  # fixing to max value for safety (could only be an issue due to tolerances).
    563                                  self._fix_var(ph, tree_node, variable, index, node_max)
    564                                  # note: we currently don't clam continuous variables!
     547                                       print "Taking no action to break cycle - length="+str(computed_cycle_length)+" does not exceed slam threshold="+str(self.CycleLengthSlamThreshold)
     548                                 elif (computed_cycle_length >= self.CycleLengthSlamThreshold) and ((ph._current_iteration - self._last_slam_iter) > self.PH_Iters_Between_Cycle_Slams):
     549                                    # we could have slammed, but we recently did and are taking a break to see if things settle down on their own.
     550                                    if index is None:
     551                                       print "Cycle issue detected with variable="+variable_name
     552                                    else:                                         
     553                                       print "Cycle issue detected with variable="+variable_name+"["+str(index)+"]"                                         
     554                                    print msg
     555                                    print "Taking no action to break cycle - length="+str(computed_cycle_length)+" does exceed slam threshold="+str(self.CycleLengthSlamThreshold)+ \
     556                                          ", but another variable was slammed within the past "+str(self.PH_Iters_Between_Cycle_Slams)+" iterations"
     557                        else:
     558
     559                           # obviously don't round in the continuous case.
     560                           node_min = value(tree_node._minimums[variable_name][index])
     561                           node_max = value(tree_node._maximums[variable_name][index])
     562
     563                           # update convergence prior to checking for fixing.
     564                           self._continuous_convergence_tracking(ph, tree_node, variable_name, index, node_min, node_max)
     565
     566                           if self._should_fix_continuous_due_to_conv(tree_node, variable, index):
     567                              # fixing to max value for safety (could only be an issue due to tolerances).
     568                              self._fix_var(ph, tree_node, variable, index, node_max)
     569                              # note: we currently don't clam continuous variables!
    565570
    566571      # TBD: the 1 might need to be parameterized - TBD - the 1 should be the PH ITERATIONS BETWEEN CYCLE SLAMS
Note: See TracChangeset for help on using the changeset viewer.