Changeset 1743


Ignore:
Timestamp:
Oct 17, 2009 4:04:22 PM (11 years ago)
Author:
jwatson
Message:

Initial commit of binary quadratic term linearization in PH - works for minimization, next commit will address maximization (minor twist).

I also added an option for disabling the linearization; default is "on", as there is little reason to believe linearization won't decrease - or at least not increase - run-time.

Location:
trunk/coopr/pysp
Files:
2 edited

Legend:

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

    r1741 r1743  
    222222      # do I disable warm-start for scenario sub-problem solves during PH iterations >= 1?
    223223      self._disable_warmstarts = False
     224
     225      # do I retain quadratic objective terms associated with binary variables? in general,
     226      # there is no good reason to not linearize, but just in case, I introduced the option.
     227      self._retain_quadratic_binary_terms = False
    224228
    225229      # PH default tolerances - for use in fixing and testing equality across scenarios,
     
    251255         elif key == "disable_warmstarts":
    252256            self._disable_warmstarts = kwds[key]
     257         elif key == "retain_quadratic_binary_terms":
     258            self._retain_quadratic_binary_terms = kwds[key]
    253259         else:
    254260            print "Unknown option=" + key + " specified in call to PH constructor"
     
    515521         print "PH is successfully initialized"
    516522         if self._output_times is True:
    517             print "Initialization time=" + str(self._init_end_time - self._init_start_time) + " seconds"
     523            print "Initialization time=%8.2f seconds" % (self._init_end_time - self._init_start_time)
    518524
    519525      # let plugins know if they care.
     
    739745
    740746                  variable_name = reference_variable.name
     747                  variable_type = reference_variable.domain
    741748
    742749                  w_parameter_name = "PHWEIGHT_"+variable_name
     
    749756                  rho_parameter = instance._component[param._ParamBase][rho_parameter_name]
    750757
     758                  instance_variable = instance._component[var._VarBase][variable_name]
     759
    751760                  for index in variable_indices:
    752761
    753                      instance_variable = instance._component[var._VarBase][variable_name][index]
    754                      
    755                      if (instance_variable.status is not VarStatus.unused) and (instance_variable.fixed is False):
    756                        
     762                     if (instance_variable[index].status is not VarStatus.unused) and (instance_variable[index].fixed is False):
     763
    757764                        # TBD - if maximizing, here is where you would want "-=" - however, if you do this, the collect/simplify process chokes.
    758                         objective_expression += (w_parameter[index] * instance_variable)
    759                         quad_expression += (rho_parameter[index] * (instance_variable - average_parameter[index]) ** 2)
    760 
     765                        objective_expression += (w_parameter[index] * instance_variable[index])
     766
     767                        if isinstance(variable_type, BooleanSet) is True:
     768
     769                           if self._retain_quadratic_binary_terms is False:
     770                              # this rather ugly form of the linearized quadratic expression term is required
     771                              # due to a pyomo bug - the form (rho/2) * (x+y+z) chokes in presolve when distributing
     772                              # over the sum.
     773                              objective_expression += ( (rho_parameter[index] / 2.0 * instance_variable[index]) - \
     774                                                        (rho_parameter[index] * average_parameter[index] * instance_variable[index]) + \
     775                                                        (rho_parameter[index] / 2.0 * average_parameter[index] * average_parameter[index]) )
     776                           else:
     777                              quad_expression += (rho_parameter[index] * (instance_variable[index] - average_parameter[index]) ** 2)
     778
     779                        else:
     780
     781                           quad_expression += (rho_parameter[index] * (instance_variable[index] - average_parameter[index]) ** 2)                           
     782                   
    761783         # strictly speaking, this probably isn't necessary - parameter coefficients won't get
    762784         # pre-processed out of the expression tree. however, if the under-the-hood should change,
  • trunk/coopr/pysp/ph_script.py

    r1740 r1743  
    178178                  action="store_true",
    179179                  dest="disable_warmstarts",
     180                  default=False)
     181parser.add_option("--retain-quadratic-binary-terms",
     182                  help="Do not linearize PH objective terms involving binary decision variables",
     183                  action="store_true",
     184                  dest="retain_quadratic_binary_terms",
    180185                  default=False)
    181186parser.add_option("--profile",
     
    334339                           verbose=options.verbose, \
    335340                           output_times=options.output_times, \
    336                            disable_warmstarts=options.disable_warmstarts)
     341                           disable_warmstarts=options.disable_warmstarts,
     342                           retain_quadratic_binary_terms=options.retain_quadratic_binary_terms)
    337343   
    338344   ph.initialize(scenario_data_directory_name=options.instance_directory, \
Note: See TracChangeset for help on using the changeset viewer.