I've a cplex constraint in the form of a a binary variable multiply for a number >= to another number.
The second number is complex to calculate, I think I need a method to compute it, it is possible in cplex write a constraint like this:
k*y[i] > method(parameter1,parameter2)
In the method I need to access to binary variables values.
Thanks a lot for replies.
Let me try this oulipo challenge.
Write an OPL models that works and that contains what you wrote.
Could this help?
float k=1.2;
dvar boolean y[1..1];
int parameter1=1;
int parameter2=2;
dvar boolean x;
dexpr float method[i in 1..10,j in 1..10]=x*(i+j);
subject to
{
forall(i in 1..1)
k*y[i] >= method[parameter1,parameter2];
}
PS: with your later comments:
float k=1.2;
dvar boolean y[1..1];
int parameter1=1;
int parameter2=2;
dvar boolean x;
float methodresults[i in 1..10,j in 1..10]; //=x*(i+j);
range r=1..10;
execute
{
function method(i,j)
{
return i+j;
}
for(var i in r) for (var j in r) methodresults[i][j]=method(i,j);
}
subject to
{
forall(i in 1..1)
k*y[i] >= x*methodresults[parameter1,parameter2];
}
If you are using a script in a .mod file, then you can define a function whithin an execute block [1]. These blocks define pre-processing or post-processing instructions written in ILOG Script [2]. Here's a trivial example from the documentation at https://www.ibm.com/support/knowledgecenter/SSSA5P_12.9.0/ilog.odms.ide.help/OPL_Studio/opllangref/topics/opl_langref_script_struct_statements_function.html.
execute {
function add(a, b) {
return a+b
}
writeln(add(1,2));
}
[1] https://www.ibm.com/support/knowledgecenter/SSSA5P_12.9.0/ilog.odms.ide.help/OPL_Studio/opllanguser/topics/opl_languser_script_intro_presynt.html
[2] https://www.ibm.com/support/knowledgecenter/SSSA5P_12.9.0/ilog.odms.ide.help/OPL_Studio/opllanguser/topics/opl_languser_script.html
Related
I am trying to perform optimization which uses the L1 regularisation method.
However, I am using cplex and I do not see an obvious way of performing L1 regularisation when I use cplex. Can someone please help?
Let me start with the example curve fitting from Model Building
Without regularization:
int n=...;
range points=1..n;
float x[points]=...;
float y[points]=...;
// y== b*x+a
dvar float a;
dvar float b;
minimize sum(i in points) (b*x[i]+a-y[i])^2;
subject to
{
}
execute
{
writeln("b=",b);
writeln("a=",a);
}
The Lasso Version (L1 regularisation) would be:
int n=...;
range points=1..n;
float x[points]=...;
float y[points]=...;
float lambda=0.1;
// y== b*x+a
dvar float a;
dvar float b;
minimize sum(i in points) (b*x[i]+a-y[i])^2+lambda*(abs(a)+abs(b));
subject to
{
}
execute
{
writeln("b=",b);
writeln("a=",a);
}
Is there a way to input a parameter (besides the seed) into a user-defined RNG in R? I understand the basics of RNGkind("user") and creating a RNG with RCPP, but I am unsure if I can defined a parameter can be used in this process. For instance, say I would want to create a function, say RNG_parameter(seed=123, multiplier=3) that simply multiplies my initialization table by a number (I wish to do more, but this example will hopefully make it easier). Essentially, this will create my user_unif_init but it will allow multiple parameters to be called. Is this possible to do? Whenever I try to create an exported function in my RCPP, it then says that: 'user_unif_rand' not in load table.
Edited: Example added (standard RNG example from Random.user)
I am looking for a way to add a parameter into a function which initializes the table, I am not sure if it can be done with user_unif_init or if I need to find another way to do it. I tried looking at Seeding a user supplied random number generator in R as similar example but RNGkind("user") wouldn't work for me when I added an exported function into the file.
#include <R_ext/Random.h>
static Int32 seed;
static double res;
static int nseed = 2;
double * user_unif_rand()
{
seed = 69069 * seed + 1;
res = seed * 2.32830643653869e-10;
return &res;
}
void user_unif_init(Int32 seed_in, int multiplier) {
seed[1]= seed_in;
seed[2]= seed_in* multiplier;
}
int * user_unif_nseed() { return &nseed; }
int * user_unif_seedloc() { return (int *) &seed; }
class Solution{
ArrayList subsetSums(ArrayList arr, int N){
int sum=0;
ArrayList<Integer> temparr = new ArrayList<>();
for(int i=1;i<=arr.size();i++)
{
for(int j = 0; i < arr.size()-i+1 ; j++)
temparr.add(recur(arr,i,j,sum));
}
return temparr;
}
int recur(ArrayList<Integer> arr,int i,int j,int sum)
{
int index = j;
int len = i;
int Sum = sum;
if(len==0)
{
return Sum;
}
Sum += arr.get(index);
return recur(arr,len--,index++,Sum);
}
}
,,,
I'm getting stack overflow error in 'return recur(arr,len--,index++,Sum);'
'''
I think, the main problem here (see comments for potential other problems) is the way you are trying to pass changed arguments to the recursive invocation:
recur(arr,len--,index++,Sum)
Actually this will call recur with the unchanged values of len and index because the operators ++ and -- (when written on the right side of a variable) are defined to return the original value of the variable and then update the variable's value.
Use (I would prefer this)
recur(arr, len-1, index+1, Sum)
or (okay, but the assignment is not needed)
recur(arr, --len, ++index, Sum)
to actually pass the modified value to the function.
Java has a recursion limit. The way to fix this is replace the recursion with a loop. (Or change the function so it does not recur as much. Infinite loops are a problem just as infinite recursion is).
A few tips for the future:
Google the documentation for errors
State the language with a tag in posts
Don't use formatting of line 1
Debug with print statements
public class Temp{
static int add(int m,int n){
if(m==0)
return n+1;
else if(n==0)
return add(m-1,1);
else
return add(m-1,add(m,n-1));
}
public static void main(String[] a){
System.out.println(add(3,3));
}
}
I am not able to understand what this function is achieving. The output for (2,2) is 7 and for (3,3) is 61. I understand that the value of n decreases then value of m and then the base case is reached but how can I get the output without running the code for a given input?
This is the Ackermann function (https://en.wikipedia.org/wiki/Ackermann_function), an example of non-primitive recursive function.
What do you mean by getting the output without running the code for a given input?
If you wish to compute a given value, I suggest you use a HashMap as a cache so that you can reuse already computed values. Also, I think you'd better use BigInteger values if you use m values greater than 3.
I have a user defined function in r:
blacksch<-function(s_0,k,sigma,r,t)
{
d1=(log(s_0/k) + (r + (sigma^2)/2)*(t))/(sigma*sqrt(t))
d2=(log(s_0/k) + (r - (sigma^2)/2)*(t))/(sigma*sqrt(t))
p=(pnorm(-d2)*k*exp(-r*t))-pnorm(-d1)*s_0
}
And I would like to use this function in c++ code that I have written using Rcpp and cppFunction. I have been through the documentation and examples a few times, but have not been successful.
bs_martin<-cppFunction('NumericMatrix compMartin (NumericMatrix st, NumericMatrix dv, double s_0, double k,
double t, double sigma, double r, int steps, int paths, Function blacksch(fun)) {
// Ensure RNG scope set
RNGScope scope;
int min_bs_step=0;
double minbsvalue=0;
vector<double> u[0]=100.0;
for(int i=1;i<=paths; i++)
{
min_bs_step=0;
for(int j=1;j<=steps;j++)
{
if (dv[i,j]>0 && min_bs_step==0)
{
min_bs_step=i;
minbsvalue=blacksch(s_0,k,sigma,r,t);
}
else if (min_bs_step!=0)
{
dv[i,j]=1 - minbsvalue;
}
}
}
return dv;
}')
I would suggest the following:
Study our documentation and examples. We show how to pass functions around too, even if we do not recommend it (for obvious performance reason, calling R from C++ ain't speedy).
If you somewhat complex example does not work, try a smaller one. At the end of the day you may just want a tester which receives two numbers and passes those to a supplied function.
And lastly: You really want blacksch in C++ too. All the statistical functions are available under the same names.