How can I can add an arithmetic constraint to my model in chocosolver - choco

I'm new to chocosolver, and i want to add an arithmetic constraint to my model. The probleme is that the constraint contains 6 Invar variables.
Here is the constraint: ((A1*B1)+(A2*B2)) / (B1+B2) = Const;
With A1, A2, B1, B2 are Intvar variables.
The arithm() method does not work here, because it takes only 3 Invars as parameters.
Thank you.

You have to decompose your equation into sub-equations and additional variables.
This can be done automatically by Choco-solver when expressions are used.
Model model = new Model();
IntVar A1 = model.intVar(1, 10);
IntVar A2 = model.intVar(1, 10);
IntVar B1 = model.intVar(1, 10);
IntVar B2 = model.intVar(1, 10);
((A1.mul(B1)).add(A2.mul(B2))).div((B1.add(B2))).eq(10);
model.getSolver().solve();
Alternatively, you can declare the additional variables and sub-equations by yourself:
Model model = new Model();
IntVar A1 = model.intVar(1, 10);
IntVar A2 = model.intVar(1, 10);
IntVar B1 = model.intVar(1, 10);
IntVar B2 = model.intVar(1, 10);
IntVar C1 = model.intVar(2, 20);
model.arithm(A1, "*", B1, "=", C1).post();
IntVar C2 = model.intVar(2, 20);
model.arithm(A2, "*", B2, "=", C2).post();
IntVar C3 = model.intVar(2,20);
model.arithm(C1, "+", C2, "=", C3).post();
IntVar C4 = model.intVar(2,20);
model.arithm(B1, "+", B2, "=", C4).post();
model.arithm(C3, "/", C4, "=", 10).post();
model.getSolver().solve();
model.getSolver().printShortStatistics();

Related

I would like to write a nested IF statement in Excel using Dates in multiple cells

I would like to have A2 = The Output Date:
B2 = A2
If B2 ="X" output Date C2
If B2 ="X" and C2="X" output Date D2
If B2 ="X" and C2="X" and D2="X" output Date E2
I tried to write the statement as
If(B2="X",C2,IF(C2="X",D2,IFD2="X"E2)))
Excel boolean chaining is sometimes unintuitive, especially so depending on your background. Try this:
=IF(B2 = "X", IF(C2 = "X", IF(D2 = "X", E2, D2), C2), "ERROR")
The idea is to check the most common condition first, then perform additional checks as they pass. This is roughly equatable to this code:
public string ExcelCheck(string b2, string c2, string d2)
{
if (b2 == "X")
{
if (c2 == "X")
{
if (d2 == "X")
return "E2";
return "D2";
}
return "C2";
}
return "ERROR";
}
You mixed up the sequence.
If you do
if(B2 = "X")
then return C2;
if(B2= "X" && condition2)
then return D2;
if(B2="X" && condition2 && condition3)
then return E2;
then it will always return C2, because that's the only condition you only ever really test.
You need to do it in this sequence:
if(B2="X" && condition2 && condition3)
then return E2;
if(B2= "X" && condition2)
then return D2;
if(B2 = "X")
then return C2;
// TODO: What if none of the conditions match ???
So It needs to look like this:
=IF(AND(B2="X",C2="X",D2="X"),E2,IF(AND(B2="X",C2="X"),D2,IF(B2="X",C2,"Define a default value please in case all conditions are wrong")))

Weight factors by eigenvalues from PROC FACTOR in SAS?

I am trying to weight the factors from PROC FACTOR by their eigenvalues, but am having some difficulty. I have a solution, but it seems to me that there should be a more direct way to do this.
** Get factors and eigenvalues;
ods output Eigenvalues=MyEigenVals
proc factor data=MyData method=principal out=MyData;
var X1 X2 X3 X4 X5 X6;
run;
ods output close;
** Transpose the eigenvalues;
proc transpose data=MyEigenVals out=MyEigenVals(drop=_NAME_) prefix=eigenval;
id Number;
var Eigenvalue;
run;
** Merge the data and fill down the eigenvalues;
data MyData;
merge MyData MyEigenVals;
retain E1 E2 E3 E4 E5 E6;
if _n_=1 then do;
E1 = eigenval1;
E2 = eigenval2;
E3 = eigenval3;
E4 = eigenval4;
E5 = eigenval5;
E6 = eigenval6;
end;
** weight each factor by its eigenvalue;
factor1 = factor1 * E1;
factor2 = factor2 * E2;
factor3 = factor3 * E3;
factor4 = factor4 * E4;
factor5 = factor5 * E5;
factor6 = factor6 * E6;
run;
As you can see this does not seem to be a very direct way of accomplishing my task. Can anyone here help me fix this up nicely? Is it even possible?
You definitely could combine it more efficiently; at minimum, you can simplify the last datastep.
data mydata;
if _n_=1 then set MyEigenVals;
set mydata;
array factor[6];
array Eigenval[6];
do _i = 1 to dim(factor);
factor[_i] = factor[_i]*eigenval[_i];
end;
run;
SET automatically retains variables.
Secondly, you may be able to skip the multiplication depending on how you're using the results. You might be able to use a weight statement to use the eigenvalues as weights - depending on what procedures you're using to later analyze the data. I don't know if that buys you much, but it could save you from modifying the original value which might be preferable.

algorithm enumerating sequences

I have an algorithmic problem.
Assume we have a sequence of labels like following
E1 B1 B2 E2 B3 E3
indexes don't have any meaning, I used them in order to distinguish between different B's and E's.
The task is enumerate all possible sequence of pairs BE that could be construct.
for example from the above example I can construct
B1 E2
B1 E3
B1 E2 B3 E3
B2 E2
B2 E3
B2 E2 B3 E3
B3 E3
I hope I found all of them, the length of the sequence (the number of pairs) is not limited of course. Pairs are always B E, where B for begin, E for end.
The problem is I cannot come up with something generic.
think this should do the trick. It's certainly not optimized though.
var labels = ['E1', 'B1', 'B2', 'E2', 'B3', 'E3'];
var results = [];
var temp_results = [];
var i, j, index, new_item;
// Utility function to add an array inside an other array if it isn't in it yet.
function pushIfNotExists(container, insert) {
var found = false;
var i, different;
container.forEach(function(item) {
if (item.length === insert.length) {
different = false;
for (i = 0; i < item.length; i++) {
if (item[i] !== insert[i]) {
different = true;
}
}
if (!different) {
found = true;
}
}
});
if (!found) {
container.push(insert);
}
}
// This loops makes the basic (2 labels) sequences.
for (i = 0; i < labels.length; i++) {
if (labels[i].charAt(0) === 'B') {
for (var j = i + 1; j < labels.length; j++) {
if (labels[j].charAt(0) === 'E') {
temp_results.push([labels[i], labels[j]]);
}
}
}
}
// This loops combines the sequences
while (temp_results.length > results.length) {
results = temp_results.slice(0);
for (i = 0; i < results.length; i++) {
index = labels.indexOf(results[i][results[i].length - 1]);
for (j = index + 1; j < results.length; j++) {
if (labels.indexOf(results[j][0]) > index) {
new_item = results[i].concat(results[j]);
if (temp_results.indexOf(new_item) === -1) {
pushIfNotExists(temp_results, new_item);
}
}
}
}
}
console.log(results);
Some (incomplete) thoughts...
E1 B1 B2 E2 B3 E3
pos 1 2 3 4 5 6
posB = indices of B // 2, 3, 5
posE = indices of E // 1, 4, 6
output = {}
append_list_of_len_2():
for i = 1 to len( posB ):
j = first elem in posE greater than i
for( ; j < len( posE ); j++ ):
output.append( {i, j} )

Strings in Matlab table

I have a string of alphabets e.g.
S = ['a';'b';'c';'d';'e'];
and I want to put it in column 3 in the table:
table(:,1) = M1; table(:,2) = d1;
disp(table)
M1 and d1 are 5 X 1 matrices of numbers each.
You could think to do as follows:
r = {M1, d1, S};
or
r = {M1; d1; S};
EDIT
you may also do this:
M1 = rand(5,1);
d1 = rand(5,1);
S = ['a';'b';'c';'d';'e'];
y = arrayfun(#(i) {M1(i), d1(i), S(i)'},1:5,'UniformOutput',false);
res = cat(1,y{:});
I'd suggest this approach to solve your question.

How can i pass an operator as an argument to a function, i am doing a calculator in C#

public int MainOperationSimplifeid(char operatoru)
{
if (beforeoperation == 2)
{
a2 = Convert.ToInt32(textBox1.Text);
textBox1.Text = "";
result = a1 operatoru a2;
// textBox1.Text = Convert.ToString(result);
a1 = 0;
a2 = 0;
}
beforeoperation++;
return result;
}
a1, a2 - represents two numbers in the program and result is the answer for the >operation peformed
i am thinking of using one single character or some other like argument that reduce all my operators used else where in the program
but i cant get the +, * as replace to a char between two integers. :(
Can you guys please help which inbult function or argument can replace all my operator to a single variable , so that i can pass that as my argument.
Thanks for going through my question :)
This sort of thing can be done with delegates. The built in delegate type Func<T1, T2, T3> represents code that accepts two parameters and returns a result.
public int MainOperationSimplifeid(Func<int, int, int> operatoru)
{
if (beforeoperation == 2)
{
a2 = Convert.ToInt32(textBox1.Text);
textBox1.Text = "";
result = operatoru(a1, a2);
// textBox1.Text = Convert.ToString(result);
a1 = 0;
a2 = 0;
}
beforeoperation++;
return result;
}
Then you can call the method with a lambda:
var addResult = MakeOperationSimplifeid((x, y) => x + y);
var multResult = MakeOperationSimplifeid((x, y) => x * y);
I think you can't make that, because the compiler needs the operator to compile the program. So, as I can see, the solution could be a enum, Something Like this:
Enum Operator {
Addition, Substraction, Multiplication, Division
};
public double MainOperationSimplified(Operator operatoru)
{
if (beforeoperation == 2)
{
a2 = Convert.ToInt32(textBox1.Text);
textBox1.Text = "";
switch (operatoru) {
case Addition:
result = a1 + a2;
break;
case Substraction:
result = a1 - a2;
break;
case Multiplication:
result = a1 * a2;
break;
case Division:
result = a1 / a2;
break;
default:
result = 0;
break;
}
a1 = 0;
a2 = 0;
}
beforeoperation++;
return result;
}

Resources