Excel Solver: Is there a way to iterate over 2 changing variables? - excel

I have an issue with solver as follows (simplified version):
So I have a nested If statement that describes condition for 2 changing variables(x,y). For example:
In one cell: IF(AND((x<=2),(x>=0.5),(y<=10),(y>=5)),1,0
The cell below it: IF(AND((x<=2.5),(x>=1.9),(y<=11),(y>=9)),1,0
The objective function is the sum of these 2 variables
Solver or goal seek (unless i give it the awnser) can't seem to get an awnser other than 0,0.
My actual problem is that i have 6 of these IF cells and I'm trying to find an (x,y) that maximizes my objective function. I want excel to go through as many combinations it can.
Any thoughts or other ways to do this? Thanks.

The reason that the Solver does not find the optimal solution in this toy problem is because the use of IF and AND statements make the problem non convex. For non-convex problems, the GRG Nonlinear solution method (the default used by solver) does not guarantee an optimal solution, as it can be trapped in locally best solutions which are not optimal.
Having said that, there is a way to formulate your problem as a mixed integer program, which, although still non-convex, can be solved with the "Simplex LP" method of Solver, and give a guaranteed maximum.
Model Setup
Here is a screenshot of the spreadsheet setup:
For convenience, I have used named ranges for the several quantities.
In particular:
- B2 --> x_var
- C2 --> x_UB1
- D2 --> x_LB1
- E2 --> x_UB2
- F2 --> x_LB2
and for row 3 I use the same convention, but instead of x_ we have y_.
The red cells (B4 and E4) have the conditions you described, and the blue cell (B5) has their sum.
For example, the condition for B4 reads
=IF(AND(x_var<=x_UB1,x_var>=x_LB1,y_var<=y_UB1,y_var>=y_LB1),1,0)
We are going to replace these expressions with two binary variables, which equal one if each expression is satisfied and zero otherwise.
The logic is that instead of an IF expression we can impose the constraints:
LB_x * z <= x <= UB_x * z
LB_y * z <= y <= UB_y * z
z is binary
then z = 1 ==> LB_x <= x <= UB_x
LB_y <= y <= UB_y
and because we maximize the sum of the two z variables, the x and y will try to fit i the corresponding ranges so that as many z as possible equal 1.
The green cells H2, J2 have the two new binary varibles, called cond1_true, cond2_true respectively. The other cells have the constraints described above:
For example, for the first expression:
J2: =x_var-cond1_true*x_UB1
J3: =y_var-cond1_true*y_UB1
K2: =x_LB1*cond1_true-x_var
K3: =y_LB1*cond1_true-y_var
All these cells need to be <= 0 in the solver model.
Solver Model:
In the mode, the objective function cell is the sum of the binary variables. The decision variables are x_var, y_yar, cond1_true, cond2_true. The constraints are all in expression <= 0 format. Here is the worksheet: https://www.dropbox.com/s/uek2k9gownhh3ni/excel-solver-is-there-a-way-to-iterate-over-2-changing-variables.xlsx?dl=0
Using this formulation, the solver goes through many combinations of variables and tries to pick up the best one. It can often guarantee an optimal solution (which is almost always the case for small problems)
UPDATE
If the intervals are non overlapping we need to modily
LB_x * z <= x <= UB_x * z
to
min(LB_x) * (1-z) + LB_x * z <= x <= UB_x * z + max(UB_x) * (1-z)
Where min(LB_x) is the minimum lower bound across all intervals (likewise for UB and for y). This way, if an x does not fall into the interval (z=0) it is only forced to fall in some other interval.
I hope this helps!

Related

Finding the optimal selections of x number per column and y numbers per row of an NxM array

Given an NxM array of positive integers, how would one go about selecting integers so that the maximum sum of values is achieved where there is a maximum of x selections in each row and y selections in each column. This is an abstraction of a problem I am trying to face in making NCAA swimming lineups. Each swimmer has a time in every event that can be converted to an integer using the USA Swimming Power Points Calculator the higher the better. Once you convert those times, I want to assign no more than 3 swimmers per event, and no more than 3 races per swimmer such that the total sum of power scores is maximized. I think this is similar to the Weapon-targeting assignment problem but that problem allows a weapon type to attack the same target more than once (in my case allowing a single swimmer to race the same event twice) and that does not work for my use case. Does anybody know what this variation on the wta problem is called, and if so do you know of any solutions or resources I could look to?
Here is a mathematical model:
Data
Let a[i,j] be the data matrix
and
x: max number of selected cells in each row
y: max number of selected cells in each column
(Note: this is a bit unusual: we normally reserve the names x and y for variables. These conventions can help with readability).
Variables
δ[i,j] ∈ {0,1} are binary variables indicating if cell (i,j) is selected.
Optimization Model
max sum((i,j), a[i,j]*δ[i,j])
sum(j,δ[i,j]) ≤ x ∀i
sum(i,δ[i,j]) ≤ y ∀j
δ[i,j] ∈ {0,1}
This can be fed into any MIP solver.

How to calculate with the Poisson-Distribution in Matlab?

I’ve used Excel in the past but the calculations including the Poisson-Distribution took a while, that’s why I switched to SQL. Soon I’ve recognized that SQL might not be a proper solution to deal with statistical issues. Finally I’ve decided to switch to Matlab but I’m not used to it at all, my problem Is the following:
I’ve imported a .csv-table and have two columns with values, let’s say A and B (110 x 1 double)
These values both are the input values for my Poisson-calculations. Since I wanna calculate for at least the first 20 events, I’ve created a variable z=1:20.
When I now calculated let’s say
New = Poisspdf(z,A),
it says something like non-scalar arguments must match in size.
Z only has 20 records but A and l both have 110 records. So I’ve expanded Z= 1:110 and transposed it:
Znew = Z.
When I now try to execute the actual calculation:
Results = Poisspdf(Znew,A).*Poisspdf(Znew,B)
I always get only a 100x1 Vector but what I want is a matrix that is 20x20 for each record of A and B (based on my actual choice of z=1:20, I only changed to z=1:110 because Matlab told that they need to match in size).
So in this 20x20 Matrix there should always be in each cell the result of a slightly different calculation (Poisspdf(Znew,A).*Poisspdf(Znew,B)).
For example in the first cell (1,1) I want to have the result of
Poisspdf(0,value of A).*Poisspdf(0,value of B),
in cell(1,2): Poisspdf(0,value of A).*Poisspdf(1,value of B),
in cell(2,1): Poisspdf(1,value of A).*Poisspdf(0,value of B),
and so on...assuming that it’s in the Format cell(row, column)
Finally I want to sum up certain parts of each 20x20 matrix and show the result of the summed up parts in new columns.
Is there anybody able to help? Many thanks!
EDIT:
Poisson Matrix in Excel
In Excel there is Poisson-function: POISSON(x, μ, FALSE) = probability density function value f(x) at the value x for the Poisson distribution with mean μ.
In e.g. cell AD313 in the table above there is the following calculation:
=POISSON(0;first value of A;FALSE)*POISSON(0;first value of B;FALSE)
, in cell AD314
=POISSON(1;first value of A;FALSE)*POISSON(0;first value of B;FALSE)
, in cell AE313
=POISSON(0;first value of A;FALSE)*POISSON(1;first value of B;FALSE)
, and so on.
I am not sure if I completely understand your question. I wrote this code that might help you:
clear; clc
% These are the lambdas parameters for the Poisson distribution
lambdaA = 100;
lambdaB = 200;
% Generating Poisson data here
A = poissrnd(lambdaA,110,1);
B = poissrnd(lambdaB,110,1);
% Get the first 20 samples
zA = A(1:20);
zB = B(1:20);
% Perform the calculation
results = repmat(poisspdf(zA,lambdaA),1,20) .* repmat(poisspdf(zB,lambdaB)',20,1);
% Sum
sumFinal = sum(results,2);
Let me know if this is what you were trying to do.

Excel: How to find closest number in table, many times

Excel
Need to find nearest float in a table, for each integer 0..99
https://www.excel-easy.com/examples/closest-match.html explains a great technique for finding the CLOSEST number from an array to a constant cell.
I need to perform this for many values (specifically, find nearest to a vertical list of integers 0..99 from within a list of floats).
Array formulas don't allow the compare-to value (integers) to change as we move down the list of integers, it treats it like a constant location.
I tried Tables, referring to the integers (works) but the formula from the above web site requires an Array operation (F2, control shift Enter), which are not permitted in Tables. Correction: You can enter the formula, control-enter the array function for one cell, copy the formulas, then insert table. Don't change the search cell reference!
Update:
I can still use array operations, but I manually have to copy the desired function into each 100 target cells. No biggie.
Fixed typo in formula. See end of question for details about "perfection".
Example code:
AI4=some integer
AJ4=MATCH(MIN(ABS(Table[float_column]-AI4)), ABS(Table[float_column]-AI4), 0)
repeat for subsequent integers in AI5...AI103
Example data:
0.1 <= matches 0
0.5
0.95 <= matches 1
1.51 <= matches 2
2.89
Consider the case where target=5, and 4.5, 5.5 exist in the list. One gives -0.5 and the other +0.5. Searching for ABS(-.5) will give the first one. Either one is decent, unless your data is non-monotonic.
This still needs a better solution.
Thanks in advance!
I had another problem, which pushed to a better solution.
Specifically, since the Y values for the X that I am interested in can be at varying distances in X, I will interpolate X between the X point before and after. Ie search for less than or equal, also greater than or equal, interpolate the desired X, then interpolate the Y values.
I could go a step further and interpolate N - 1 to N + 1, which will give cleaner results for noisy data.

Excel gives weird R square calculations?

This is really weird. I calculate R^2 values with Excel in two different ways and the results differ hugely. Why?
1) First I use Excel to do a linear regression via a graph, and use the "Add Trendline..." right mouse button functionality to specify Intercept = 0. The R square value shows -3.253. The regressed equation is Y = -0.1321 * X
2) Then I use Excel to do a linear regression via LINEST function. I highlight 5x2 rows and in the top left cell, I type "=LINEST ([Y vector]; [X vector], FALSE, TRUE). The False means the intercept is 0, and the True means Excel should print additional regression statistical information. Then I press CTRL + SHIFT + Enter. This will show me additional statistics, such as R^2 value in the third left cell. Which turns out to be 0.11166. The regressed equation is Y = -0.1321 * X
My question is; what am I doing wrong in calculating R^2 with the graph? Python and statsmodels.api confirms that R^2 is 0.11166, and the regressed equation is Y = -0.1321 * X.
Y =
0.0291970802919708
0.141801551718973
0.145668034655723
0.0691229530946433
0.0431577486597426
0.133618351873374
X =
-0.35551988
-0.20577599
0.10780785
-0.25028796
-0.42762184
0.02442197
Your calculation is correct. Scatter plot does not return correct R^2 when the intercept is 0. This is an formula fo R^2
where
If you use standard regression model, you use average value of y as y̅. But when you assume that the intercept equals 0, you need to set y̅ as zero. If you use the average value of y instead of zero, you get the R^2 = -3.252767.
You can see the calculation here. The SStot wrong column uses average value of y as y̅. Then the R^2 value equals to -3.252767. If you use 0 (as I did in SStot right column), then you get 0.111.
It is an old bug described by Microsoft here:https://support.microsoft.com/en-us/help/829249/you-will-receive-an-incorrect-r-squared-value-in-the-chart-tool-in-excel-2003
You need to use the LINEST function to get correct R^2 value.
Me and my fellow engineers just got tangled up in this. Based on this discussion and what we observed, the R^2 is wrong all of the time except when Excel calculates the best y-intercept. Any other y-intercept (either forced through Zero OR user-defined), is wrong.

How do I constrain a value to a range in excel?

In C++ I would use boost::clamp for this. Basically I have some excel function
A1*B2+C3+D4
I want to do constrain it to +/- some number, call it X1. The obvious way is this:
MAX(-X1, MIN(X1, A1*B2+C3+D4))
But I want to be able to do this:
CLAMP(A1*B2+C3+D4, -X1, X1)
Does this or something similar exist? I'm just curious - obviously the workaround works, it's just ugly.
This can be done using MEDIAN. MEDIAN picks the middle of the three values, thus effectively restricting the lower and upper limits.
For example say your minimum is 5 and your maximum is 10:
=MEDIAN(5,0,10) is 5
=MEDIAN(5,7,10) is 7
=MEDIAN(5,12,10) is 10
With spreadsheet formulas I don't think that you can do much better than that min/max construct. You could write clamp in VBA:
Function clamp(x As Double, lower As Double, upper As Double) As Double
If x < lower Then
clamp = lower
ElseIf x > upper Then
clamp = upper
Else
clamp = x
End If
End Function
If you enter that in a standard code module then you could e.g. do something like this:
In column A I have values in the range 0 to 2*pi. In C2 I have the value 0.5. In B1 I entered
=clamp(SIN(A1),-$C$2,$C$2)
and copied down. The graph shows the result.
(Since I gave a VBA solution I'll add the Excel-VBA tag. Even if you prefer a non-VBA solution, it is possible that others in the future might search the question and be comfortable with a VBA solution).

Resources