How to speed-up Ortools during creation of variables - or-tools

I have a very large problem and I am facing computational time issues even in the declaration of the variables in OrTools (>10minutes).
Here is a peace of my code
x = {}
for i in setI:
for j in setJ:
x[i,j] = model.NewIntVar(0, 1, 'x[{}]'.format([i,j]))
If a create the same variable using Pyomo I do not face this problem, I believe I am doing something wrong.
Can someone, please, help me to improve the performance of my algorithm?
Thanks

Related

Is there any way to vectorize the matlab code or another approach to reduce its running time?

Is there anyway to improve the below codes? It takes much time in higher values. I'd be appreciated if a solution for improving be advised.
term3=0;
ngrain=70;
etas = rand(512*512,70);
glist = round(1,70);
en = zeros(1,70);
for i=1:70
en(i)=0.493;
end
for igrain=1:ngrain
for jgr=1:ngrain+nrex
if(glist(jgr)== 1)
den(igrain,jgr)=en(jgr)-en(igrain);
term3=term3-8/pi*(etas(:,igrain).*etas(:,jgr)).^0.5*den(igrain,jgr);
end
end
end
please be more precise in the future. Here are a couple of hints to improve your coding:
Building a vector out of constants can be achieved in several ways (unfortunately, you picked the least efficient one):
a for-loop (with or without pre-allocation of memory, you did allocate, so that is good!)
use 1 * constant => ones(1,70)*0.493
repeat the 1x1 matrix: repmat() => repmat(1,70,0.493) (this is the most efficient approach, you may check this using tic() and toc() )
Anyway, this wasn't your bottleneck.
You can do logical comparisons directly instead of looping and using if:
lg = glist == 1;
idx = find(lg);
for i = 1:length(idx)
jgr = idx(i)
end
Note that your example does not work because nrex is not defined. It would also be great if you format your code nicer (consistent spacing, indention, a naming that is a bit more intuitive)

Why is SCIP taking so long and taking so much memory?

I'm using the SCIP solver in the OPTI toolbox in matlab to solve a quadratic optimization problem with integer constraints. I ran it with the following specs and it's been running for a day and has already taken up 55GB of ram in my system and still counting. I'm new to optimization in matlab, am I doing something wrong or is this usual? I tried with less maxnodes and maxtime, but the program stops with the 'Node limit reached' error in those cases. Here's the code (H, Aeq etc. have been defined earlier in the code) -
X = sym('X%d%d', [104 1]);
fun = #(X) 1/2*X'*H*X;
options = optiset('solver', 'SCIP', 'maxnodes', 20000000, 'maxtime', 100000);
Opt = opti('fun', fun, 'eq', Aeq, Beq, 'xtype', xtype, 'options', options);
[xval,fval,exitflag,info] = solve(Opt)
This is not unusual if the quadratic function(s) are nonconvex. This easily leads to hard problems that cannot be solved to proven optimality with today's algorithms in any reasonably finite amount of time. Note that this does not only depend on the size of the problem, but in general smaller problems (of a similar type) will be easier.
This being said, SCIP might already have found a near-optimal solution that is accessible even when the time or node limit is exceeded.

How to adapt my for loop to get it working with parfor of Matlab? (ODE solver)

Ive come a long way with programming as a newbie in Matlab, but now Im really stuck. Ive tried to 'slice' the variable dy, but unfortunately it didnt work. I guess the problem lies in the fact that i is dependent on SACn. Ive done this because the ODE solver needs a vector as input, not a matrix. Can someone please help me?
This is a snippet of code:
parfor SACn=0:SACnum-1
i=19+SACn*200:1:66+SACn*200;
dy(i-18+100,:) = alpha.*(1-y(i-18+100,:)).*(1./(1+exp(-((y(i,:) -th1)./k1))))-beta.*y(i-18+100,:); %#ok<*PFBNS,*PFPIE>
dy(i-18+150,:) = alpha.*(1-y(i-18+150,:)).*(1./(1+exp(-((y(i-18+100,:)-th2)./k2))))-beta.*y(i-18+150,:);
end
I tried something like this (didnt work though):
parfor SACn=0:SACnum-1
temp1dy=zeros(200,size(y,2));
temp2dy=zeros(200,size(y,2));
for i=19:1:66
temp1dy(i-18+100,:) = alpha.*(1-y(i-18+100,:)).*(1./(1+exp(-((y(i,:) -th1)./k1))))-beta.*y(i-18+100,:); %#ok<*PFBNS,*PFPIE>
temp2dy(i-18+150,:) = alpha.*(1-y(i-18+150,:)).*(1./(1+exp(-((y(i-18+100,:)-th2)./k2))))-beta.*y(i-18+150,:);
end
dy(SACn*200+1:(SACn+1)*200,:)=temp1dy;
dy(SACn*200+1:(SACn+1)*200,:)=temp2dy;
end
Additional info: I have vectorized my code in an ODE solver of Matlab, these are all the :) 's you see at the end of all variables such as y(i+18-100,:). Ive done this so that the ODE solver computes multiple values of dy for the same time point in parallel and then chooses the best option.
Please do not hesitate to ask for more details!

Calling several of the same component in Modelica

I seem to struggle with a modeling problem in Modelica (using Dymola), and I hereby seek your help. The idea is this:
I have modeled some components (models) that I want to connect together through their ports. The models are working. The thing is I want to connect several of the same unit (called myUnit in the pseudo code below) in a series. If the number of units were, let's say, only 5 then I could easily dragged them out 1-by-1 and connected them in a standard manner, but let's say I want 100 units. Is there an easy and elegant way to do this? I don't believe for loops to be working outside the equation part of the model, and I want an elegant way of naming the units. I'll try to illustrate this by doing a pseudo code below, explaining what I wish to achieve:
model someModel
parameter Integer n = 100 "Length of series";
parameter Real optionValue = 123;
myLibrary.myStartUnit startUnit(someOption = optionValue); // First unit
for i in 2:n-1 loop
myLibrary.myUnit unit_'num2str(i)'(someOption = optionValue); // i'th unit
end for;
myLibrary.myEndUnit endUnit(someOption = optionValue); // Last unit
equation
connect(startUnit.outPort,unit_1.inPort);
for i in 2:n-1 loop
connect(unit_'num2str(i)'.outPort,unit_'num2str(i+1)'.inPort)
end for;
connect(unit_'num2str(n-1)'.outPort,endUnit.inport);
end someModel;
I hope I've managed to explain my problem properly, now.
Any tips for solving this problem? I greatly appreciate both strategic advice as to solve the problem as well as purely syntactic advice.
In advance, thanks for all help. :)
You can use arrays to achieve this. For example, using models of the Modelica standard library:
model ArrayDemo
parameter Integer n = 10 "Number of springs/masses";
Modelica.Mechanics.Translational.Sources.ConstantForce constantForce(f_constant=100);
Modelica.Mechanics.Translational.Components.Spring springs[n];
Modelica.Mechanics.Translational.Components.Mass masses[n];
Modelica.Mechanics.Translational.Components.Fixed fixed;
equation
connect(constantForce.flange, springs[1].flange_a);
for i in 1 : n - 1 loop
connect(springs[i].flange_b, masses[i].flange_a);
connect(masses[i].flange_b, springs[i + 1].flange_a);
end for;
connect(springs[n].flange_b, masses[n].flange_a);
connect(masses[n].flange_b, fixed.flange);
end ArrayDemo;
The idea is to declare the components using arrays and then connect them using for loops.

Avoiding loops in MatLab code (barycentric weights)

After having learned basic programming in Java, I have found that the most difficult part of transitioning to MatLab for my current algorithm course, is to avoid loops. I know that there are plenty of smart ways to vectorize operations in MatLab, but my mind is so "stuck" in loop-thinking, that I am finding it hard to intuitively see how I may vectorize code. Once I am shown how it can be done, it makes sense to me, but I just don't see it that easily myself. Currently I have the following code for finding the barycentric weights used in Lagrangian interpolation:
function w = barycentric_weights(x);
% The function is used to find the weights of the
% barycentric formula based on a given grid as input.
n = length(x);
w = zeros(1,n);
% Calculating the weights
for i = 1:n
prod = 1;
for j = 1:n
if i ~= j
prod = prod*(x(i) - x(j));
end
end
w(i) = prod;
end
w = 1./w;
I am pretty sure there must be a smarter way to do this in MatLab, but I just can't think of it. If anyone has any tips I will be very grateful :). And the only way I'll ever learn all the vectorizing tricks in MatLab is to see how they are used in various scenarios such as above.
One has to be creative in matlab to avoid for loop:
[X,Y] =meshgrid(x,x)
Z = X - Y
w =1./prod(Z+eye(length(x)))
Kristian, there are a lot of ways to vectorize code. You've already gotten two. (And I agree with shakinfree: you should always consider 1) how long it takes to run in non-vectorized form (so you'll have an idea of how much time you might save by vectorizing); 2) how long it might take you to vectorize (so you'll have a better sense of whether or not it's worth your time; 3) how many times you will call it (again: is it worth doing); and 3) readability. As shakinfree suggests, you don't want to come back to your code a year from now and scratch your head about what you've implemented. At least make sure you've commented well.
But at a meta-level, when you decide that you need to improve runtime performance by vectorizing, first start with small (3x1 ?) array and make sure you understand exactly what's happening for each iteration. Then, spend some time reading this document, and following relevant links:
http://www.mathworks.com/help/releases/R2012b/symbolic/code-performance.html
It will help you determine when and how to vectorize.
Happy MATLABbing!
Brett
I can see the appeal of vectorization, but I often ask myself how much time it actually saves when I go back to the code a month later and have to decipher all that repmat gibberish. I think your current code is clean and clear and I wouldn't mess with it unless performance is really critical. But to answer your question here is my best effort:
function w = barycentric_weights_vectorized(x)
n = length(x);
w = 1./prod(eye(n) + repmat(x,n,1) - repmat(x',1,n),1);
end
Hope that helps!
And I am assuming x is a row vector here.