I am not srue whether this is really a mathematical question, or actually a mathematica question. :D
suppose I have a matrix
{{4/13 + (9 w11)/13 + (6 w12)/13,
6/13 + (9 w21)/13 + (6 w22)/13}, {-(6/13) + (6 w11)/13 + (4 w12)/
13, -(9/13) + (6 w21)/13 + (4 w22)/13}}
with w11, w12, w21, w22 as free parameters.
And I know by visual inspection that 3*w11+2*w12 can be represented as one variable, and 3*w21+2*w22 can be represented as another. So essentially this matrix only has two independent variables. Given any matrix of this form, is there any method to automatically reduce the number of independent variables? I guess I am stuck at formulating this in a precise mathematical way.
Please share your thoughts. Many thanks.
Edit:
My question is really the following.
Given matrix like this
{{4/13 + (9 w11)/13 + (6 w12)/13,
6/13 + (9 w21)/13 + (6 w22)/13}, {-(6/13) + (6 w11)/13 + (4 w12)/
13, -(9/13) + (6 w21)/13 + (4 w22)/13}}
or involving some other symbolical constants
{{a+4/13 + (9 w11)/13 + (6 w12)/13,
6/13*c + (9 w21)/13 + (6 w22)/13}, {-(6/13)/d + (6 w11)/13 + (4 w12)/
13, -(9/13) + (6 w21)/13 + (4 w22)/13}}
I want to use mathematica to automatically identify the number n of independent variables (in this case is 2), and then name these independent varirables y1, y2, ..., yn, and then re-write the matrix in terms of y1, y2, ..., yn instead of w11, w12, w21, w22.
Starting with
mat = {{4/13 + (9 w11)/13 + (6 w12)/13,6/13 + (9 w21)/13 + (6 w22)/13},
{-(6/13) + (6 w11)/13 + (4 w12)/13, -(9/13) + (6 w21)/13 + (4 w22)/13}};
Form a second matrix, of indeterminates, same dimensions.
mat2 = Array[y, Dimensions[mat]];
Now consider the polynomial (actually linear) system formed by setting mat-mat2==0. We can eliminate the original variables and look for dependencies amongst the new ones. Could use Eliminate; I'll show with GroebnerBasis.
GroebnerBasis[Flatten[mat - mat2], Variables[mat2], Variables[mat]]
Out[59]= {-3 + 2 y[1, 2] - 3 y[2, 2], -2 + 2 y[1, 1] - 3 y[2, 1]}
So we get a pair of explicit relations between the original matrix elements.
---edit---
You can get expressions for the new variables that clearly indicates the dependency of two of them on the other two. To do this, form the Groebner basis and use it in polynomial reduction.
gb = GroebnerBasis[Flatten[mat - mat2], Variables[mat2], Variables[mat]];
vars = Flatten[mat2];
PolynomialReduce[vars, gb, vars][[All, 2]]
Out[278]= {1 + 3/2 y[2, 1], 3/2 + 3/2 y[2, 2], y[2, 1], y[2, 2]}
---end edit---
Daniel Lichtblau
Wolfram Research
Related
I have a challenge to find number of ways to get a sum of a given number from an array containing coins. For example:
coins: {2,3,5,7}
sum: 8
total ways: 6 -> (2 + 2 + 2 + 2), (2 + 3 + 3), (3 + 2 + 3), (3 + 3 + 2), (3 + 5), and (5 + 3).
I have the solution that works using dp pseudo code:
build an array ar of size "sum"
ar[0]=1
for i = 1 to sum do:
ar[i]=ar[i-2]+ar[i-3]+ar[i-5]+ar[i-7]
return ar[sum]
As mentioned this code works fine, but the platform I am running this in can have sum as large as 1019, and as expected it gives me a timeout. Is there any other way this can be dealt with? I have even tried to reduce the size of the array when it goes beyond size i-largest value in coins. But that as well times out.
In chess, one player can have different material combinations, for example:
"1 queen, 2 rooks, 2 knights, 2 bishops, 8 pawns + the king" is one combination
if the player loses one bishop:
"1 queen, 2 rooks, 2 knights, 1 bishop, 8 pawns + the king" is another combination
..afterwards, if a pawn is promoted to a knight, then:
"1 queen, 2 rooks, 3 knights, 1 bishop, 7 pawns + the king" is another combination
OK, the following combination is not valid:
"5 queens, 5 rooks, 5 knights, 5 bishops, 2 pawns + the king"
since you lack of pawns to promote. (5 queens = 4 pawns needed) (5 rooks = 3 pawns needed) , etc. so 4 + 3 + 3 + 3 = 13 pawns needed. Since 2 pawns on the board, then at most 6 pawns could be promoted. Not valid.
How many valid material combinations are there?
I computed 8694 combinations using the following C code. The question is:
Do you find simpler/efficient algorithm to calculate it? (less cycles, less calculations, clearer code, etc.) ... or even a math formulae??
total = 0;
for (queens=0;queens<=9;queens++)
for (rooks=0;rooks<=10;rooks++)
for (bishops=0;bishops<=10;bishops++)
for (knights=0;knights<=10;knights++)
for (pawns=0;pawns<=8;pawns++)
{
pawnsRequested = 0;
if (queens>1) pawnsRequested += queens - 1;
if (rooks>2) pawnsRequested += rooks - 2;
if (bishops>2) pawnsRequested += bishops - 2;
if (knights>2) pawnsRequested += knights - 2;
if (8-pawns < pawnsRequested) continue;
total++;
}
printf("%i\n",total);
If the piece types were independent, then we could just multiply: 10 possibilities for the queens times 11 possibilities for the rooks times etc. We need to track pawn usage, however. There's a mathematical trick called generating functions where we can encode the possibilities for, e.g., rooks as
3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8,
where the power of x denotes the number of pawns used, and the coefficient denotes the number of possibilities. Here, there are three possibilities that require no promoted pawns (0, 1, 2), one that requires one promoted pawn (3), one that requires two promoted pawns (4), etc. Now we can multiply each of the factors together (respectively, queens, rooks, bishops, knights, pawns).
(2 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (3 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
* (1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8)
Here it is from Wolfram Alpha.
The coefficients of 1 through x^8, which are the number of possibilities for 0 to 8 pawns required, are 54, 135, 261, 443, 693, 1024, 1450, 1986, 2648, summing to 8694.
if we have n different things and we need to distribute them among m different people then how many ways can we do it such that for each of the m persons there is conditions that:
person 1 can have at least a things and at most b things
person 2 can have at least c things and at most d things
.. and so on ?
e.g if n = 5 and m =3 and the conditions are:
person 1 can receive at least 0 and at most 1 gift
person 2 can receive at least 1 and at most 3 gift
person 3 can receive at least 1 and at most 4 gift
then the number of ways of distributing these 5 gifts is 6((0 1 4), (0 2 3), (0 3 2), (1 1 3), (1 2 2), (1 3 1)).
One way i believe is to iterate through all possible combinations for each range and see which ones sum upto n , but can't think of an efficient algorithm.
Thanks
You probably want to use a generating function approach. Represent the number of objects that person i gets by the exponents of x. This means that if person i can have at least 3 and at most 7 things, this corresponds to the term
x^3 + x^4 + x^5 + x^6 + x^7
Remember to think of + as OR and * as AND. If we want to impose conditions and person 1 and person 2, then multiply their functions together. For example, with person 1 having between 3 and 7 things, and say person 2 has at least 5 things, and add a third person with at most 10 things. Then we get:
(x^3 + x^4 + x^5 + x^6 + x^7) * (x^5 + x^6 + ... ) * (1 + x + x^2 + ... + x^10)
which can also be written as
(x^3 + x^4 + x^5 + x^6 + x^7) * ( x^5/(1+x) ) * (1 + x + x^2 + ... + x^10)
The way to get information back from this is the following. The coefficient of x^M in the expansion of these terms gives the number of ways to distribute a total of M things among all the people subject to the given constraints.
You can work this out from the formulas, or write a program to extract the coefficient, but the idea is to use generating functions as a convenient and efficient way to encode the constraints along with the answer.
Given an array like
1, 6, 5, 2, 3, 4
we need to print
1 2 3
1 3 4
1 2 4
2 3 4
What is the best way to do this?
Is this dynamic programming?
Is there a better way to do than the bruteforce O(n3)? I am sure there is.
The reason I say dynamic programming is because I can see this as something like
for '1' (print all results of sub problem of the rest of the array with subsequences of size 2).
for '2' (print all results of sub problems of the rest of the array with subseqences of size 2)
and go on like this.
However, there is a lot of overlap in the above two results, so we need to find an efficient way of reusing that, I guess.
Well, these are just random thoughts. You can correct me with the right appraoch.
OK, let me correct, if not print, I need the different increasing sequences returned. My point is, I need to find an approach to get to these sequences in the most efficient way.
You can walk through the array and remember what partial sequences are possible until the current point. Print and forget any sequences that reach length 3.
Example:
(1 6 5 2 3 4)
^
remember ((1))
(1 6 5 2 3 4)
^
remember ((1) (1 6) (6))
(1 6 5 2 3 4)
^
remember ((1) (1 6) (6) (1 5) (5))
(1 6 5 2 3 4)
^
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2))
(1 6 5 2 3 4)
^
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2) (1 3) (1 2 3) (2 3) (3))
print and forget (1 2 3)
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2) (1 3) (2 3) (3))
(1 6 5 2 3 4)
^
remember ((1) (1 6) (6) (1 5) (5) (1 2) (2) (1 3) (2 3) (3) (1 4) (1 2 4) (2 4)
(1 3 4) (2 3 4) (3 4) (4))
print and forget (1 2 4)
print and forget (1 3 4)
print and forget (2 3 4)
done.
The challenge seems to lie in the choice of an appropriate data structure for the remembered subsequences.
In the generalized case you have to calculate the complexity based on two things:
1- Count of input numbers (I will call it b)
2- Length of output (I will call it d)
A generalized method that I can think of, is to construct an analogous graph to the problem in O(n^2):
If a larger number comes after a smaller number, There is a directed edge from smaller one to it.
Now in order to find all sequences of length d, You need to start from each number and output all paths of length (d - 1).
If you use a traversal method like BFS the complexity will be less than O(d x (b ^ (d - 1))).
However you can use adjacent matrix multiplication to find the paths of length d, which will bring the complexity down to something less than O((d - 2) x (b ^ 3)). (Nth power of an adjacency matrix will tell you how many paths exist from each node to another with length of N).
There are algorithms to reduce square matrix multiplication complexity a bit.
Create a list of ordered pairs (a,b) such that a<b and Index(a) < Index(b). O(n^2)
Sort this list (on either a or b -- doesn't matter) in O(n^2log(n)). Can be made O(nlog(n)) depending on data structure.
For each element in the list, find all matching ordered pairs using binary search -- worst case O(n^3log(n)), average case O(n^2log(n))
I am testing an infix-to-postfix-to-infix converter and found some kind of uncertainty. For example, a simple infix sum
1 + 2 + 3 + 4
can be converted to postfix one
1 2 + 3 + 4 +
assuming that operators with equal precedence are not accumulated. If they are then I get
1 2 3 4 + + +
On the other hand, all the following postfix expressions can be converted to the initial sum
1 2 + 3 + 4 +
1 2 + 3 4 + +
1 2 3 4 + + +
Are all these postfix expressions correct?
UPDATE1
If you would make such converter, to which form would you choose? I need to choose one for testing.
You need to define an extra constraint.
Mathematically, your postfix expressions are all the same. But on a computer integer addition is not really commutative because of overflow.
Replace 1 2 3 4 with a b c d and consider the possibility of overflow. Most programming languages define that a + b + c + d must be evaluated left-to-right so that a b + c + d + is the only correct translation.
Only when you define that the order of evaluation is 'unspecified' all the postfix versions are equivalent. That was the case for (older) C Compilers.
Yep, all correct. They correspond to the following bracketed infix expressions:
((1 + 2) + 3) + 4
(1 + 2) + (3 + 4)
1 + (2 + (3 + 4))
+ is confusing - it is commutative, so in fact, every result seems correct.
Consider replacing + with other operators: 1 a 2 b 3 c 4.
The correct result here, for left-associative operators, is
1 2 a 3 b 4 c
So, in your case, I'd expect 1 2 + 3 + 4 +