[FlopCpp] Using "symbolic" variable names.
marc.roth at rwe.com
marc.roth at rwe.com
Mon Nov 8 05:16:36 EST 2010
Hi Christian,
Thank you for replies. In the mean time I have played around a bit more with issues 2) and have reached a working version of that "encapsulating" function. It is not very elegant, though. In order not need to deal with destruction of objects instantiated through "new" I am using boost's shared_ptr. Nevertheless, because such objects get destroyed when last reference to objects go out of scope, I have to pass back all MP_* related objects back to caller's scope (even for locally created and used MP_set variables, such as 'abs_x_set' below). Hence, I have resorted to pass back all the MP_* objects via references to the caller, although this makes the entire encapsulating thing a bit questionable.
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<MP_set> MP_set_ptr;
typedef boost::shared_ptr<MP_variable> MP_var_ptr;
typedef boost::shared_ptr<MP_expression> MP_expr_ptr;
typedef boost::shared_ptr<MP_constraint> MP_cnstr_ptr;
typedef boost::shared_ptr<MP_model> MP_model_ptr;
static MP_expr_ptr
lp_objective_absolute(
MP_variable& x,
MP_data& weight,
MP_set_ptr& abs_x_set_ptr,
MP_var_ptr& abs_x_var_ptr,
vector<MP_cnstr_ptr>& abs_x_linctr,
MP_model& lp/*=MP_model::getDefaultModel()*/,
const string& prefix/*="abs_"*/) {
if (x.size() > 0) {
if (x.getName().empty()) {
string message;
message += "decision variable(s) or affine expression(s) is/are not named";
throw BmtException(message.c_str());
}
// create required MP_* objects as automatic variables
MP_set_ptr abs_x_set(new MP_set(x.size()));
MP_var_ptr abs_x_var(new MP_variable(*abs_x_set));
MP_cnstr_ptr abs_x_linctr_a(new MP_constraint(*abs_x_set));
MP_cnstr_ptr abs_x_linctr_b(new MP_constraint(*abs_x_set));
// set-up names
string abs_x_name(prefix + x.getName());
abs_x_set->setName(abs_x_name + "_set");
(*abs_x_var).setName(abs_x_name);
abs_x_linctr_a->setName(abs_x_name + "_cnstr_a");
abs_x_linctr_b->setName(abs_x_name + "_cnstr_b");
// set-up bounds and constraints
(*abs_x_var).lowerLimit(*abs_x_set) = 0.0;
(*abs_x_linctr_a)(*abs_x_set) = +1.0*x(*abs_x_set) <= (*abs_x_var)(*abs_x_set);
(*abs_x_linctr_b)(*abs_x_set) = -1.0*x(*abs_x_set) <= (*abs_x_var)(*abs_x_set);
// add constraints to model
lp.add(*abs_x_linctr_a);
lp.add(*abs_x_linctr_b);
// assign automatic variables to out parameters
// in order to prevent destruction of MP_* objects.
abs_x_set_ptr = abs_x_set;
abs_x_var_ptr = abs_x_var;
abs_x_linctr.push_back(abs_x_linctr_a);
abs_x_linctr.push_back(abs_x_linctr_b);
MP_expr_ptr objective(new MP_expression(sum(*abs_x_set, weight(*abs_x_set)*(*abs_x_var)(*abs_x_set))));
return objective;
} else {
return MP_expr_ptr();
}
}
-----Original Message-----
From: Christian Wolf [mailto:kalmar at uni-paderborn.de]
Sent: 06 November 2010 18:34
To: flopcpp at list.coin-or.org; Roth, Marc (RWE Trading)
Subject: Re: [FlopCpp] Using "symbolic" variable names.
Hello Marc,
Am 05.11.2010 17:55, schrieb marc.roth at rwe.com:
Hi,
I am developing a toy problem in order to figure out how FlopC++ has to be used. I consulted the example problems in the examples section to get started but have a couple of questions:
1) Use of symbolic names and LP file output: I would like to use the setName method on MP_variable, lets say, such as
MP_model lp(new OsiCbcSolverInterface) ;
MP_set T(123);
MP_variable dispatch_period_volume(T);
x.setName("dp_volume_");
Once the model has been set up, I write the problem to a file, such as
lp.attach();
lp.Solver->writeLp("c:\\temp\\bmt);
What I expect to see in the file bmt.lp is that the variable names are printed like dp_volume_1, dp_volume_2, ..., dp_volume_124, but what I get is only x1, ..., x124. Am I doing something wrong or is this feature not supported (in this case what is the MP_variable::setNames() method for?).
At the moment the feature is not yet supported, but it will be in the near future, at least in the stochastic branch of FlopC++.
2) In the objective function in question some of the decision variables x are modelled by abs(x) (the absolute value of x). Obviously this is not a linear construct, but can be modelled as:
x <= abs_x
-1.0*x <= abs_x
0 <= abs_x
Because I require various variables to be modelled as abs(.) I would like to implement a function that;
A) creates the auxiliary variable(s) abs_x for each such x,
B) adds above constraints/bounds to the model, and
C) returns a MP_expression that can be added to the objective function expression in terms of the abs_x variables.
I.e., I would like to delegate/encapsulate all issues to model the absolute value of a decision variable to a function.
My initial approach, listed below, failed miserably because of the issue of automatic variables and copy constructors, etc., I guess boiling down to that FlopC++ elements are not "shallow" copied and reference counted on the one had and that MP_variables are not added to the model implicitly but only through their use in constraints and objective function. What is the proper way to accomplish this?
In my opinion this could work, if you work with pointers instead of objects in your helper function. Create the MP_constraints and MP_variables in the function with new, otherwise they should be lost when the function goes out of scope. This is only a first thought about the topic. I can look into it someday next week.
Hope this helps,
Christian
static MP_expression
lp_objective_absolute(
MP_variable& x,
MP_data& weight,
MP_model& lp/*=MP_model::getDefaultModel()*/,
const string& prefix/*="abs_"*/) {
if (x.size() > 0) {
if (x.getName().empty()) {
string message;
message += "decision variable(s) or affine expression(s) is/are not named";
throw BmtException(message.c_str());
}
MP_set D(x.size());
MP_variable abs_x(D);
abs_x.setName(prefix + x.getName());
abs_x.lowerLimit(D) = 0.0;
MP_constraint abs_x_linctr_a(D);
MP_constraint abs_x_linctr_b(D);
abs_x_linctr_a(D) = x(D) <= abs_x(D);
abs_x_linctr_b(D) = -1.0*x(D) <= abs_x(D);
lp.add(abs_x_linctr_a);
lp.add(abs_x_linctr_b);
return sum(D, weight(D)*abs_x(D));
} else {
return MP_expression();
}
}
And would be used such as
MP_expression objective;
MP_data UNIT_WEIGHT_X(T);
UNIT_WEIGHT_X(T) = 1.0;
objective = lp_objective_absolute(dispatch_period_volume, UNIT_WEIGHT_X, lp);
Best Regards/Mit freundlichen Grüßen
Marc Roth
External Consultant,
Structuring & Valuation
Tel.: +41 55 534 44 82
Mob: +44 7795 276 136
Fax: +41 55 534 44 82
mailto:marc.roth at rwe.com <mailto:marc.roth at rwe.com>
yahoo:nerdyanorak
RWE Supply & Trading GmbH
London Branch
130 Wood Street
London EC2V 6DL
United Kingdom
Advisory Board:
Dr. Ulrich Jobs (Chairman)
Board of Directors:
Stefan Judisch (CEO)
Dr. Bernhard Günther
Dr. Peter Kreuzberg
Richard Lewis
Alan Robinson
Head Office: Essen, Germany
Registered at the County Court of Essen
Commercial Registry No.: HRB 14327
Sales Tax Identification No. DE 8130 22 070
_______________________________________________
FlopCpp mailing list
FlopCpp at list.coin-or.org
http://list.coin-or.org/mailman/listinfo/flopcpp
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://list.coin-or.org/pipermail/flopcpp/attachments/20101108/605f8728/attachment.html
More information about the FlopCpp
mailing list