A task for generating most variety sprites to build a landscape tileset - combinations

We are given a number of basic sprites that are spread out over several layers. To generate a single tile we need to take any sprite from each layer and overlay them one by one.
For example:
Layer 1: Sea/Shore/Land
Layer 2: Rocks
Layer 3: Peak/ Plateau
Layer 4: Grass
Layer 5: Decorative elements
The number of sprites in each layer is arbitrary, but can only be within [1...16].
The number of layers is also arbitrary, but can only be within [1...6]
You need to get 16 or less (if more is impossible to generate) unique tiles, composed of as many different combinations of original sprites as possible - that is, the less they or their combinations will be repeated for different tiles, the better. Except for the first layer, for which the sprites must go in sequence for every next resulting set (see example below).
Example:
For:
{{a0, a1, a2}, // layer 1
{b0, b1, b2}, // layer 2
{c0, c1, c2}} // layer 3
The result should be something like this:
a0 b0 c0
a1 b1 c1
a2 b2 c2
a0 b1 c2
a1 b2 c0
a2 b0 c1
a0 b2 c1
a1 b0 c2
a2 b1 c0
a0 b0 c1
a1 b1 c2
a2 b2 c0
a0 b1 c0
a1 b2 c1
a2 b0 c2
a0 b0 c2
It seems to me that there are two ways of solving this problem:
Each layer is basically a one-dimensional set. To obtain all possible combinations, it is enough to perform Cartesian product of these sets. Then sort the resulting sets by " variety". 
But in this case there are two difficulties:
There can be quite a lot of combinations (we need only 16 of them).
It is necessary to compare not only the sets among themselves, but also with the already selected ones, in terms of the frequency of occurrence of the combinations included in them.
Build the most variety combinations straight away.
I have to admit that I'm stuck on both options - the first on the sorting algorithm, the second on the generation algorithm. I ask for help or hints.
I write in C++, but hints and solutions could be in any - the main thing for me to understand the idea.

Related

[spreadsheet][libreoffice-calc] Efficient checks of: 1. row number between columns; 1. formulas between rows in same columns

I looked up how I can check efficiently whether:
I. the row number of each cell address matches with the row number, e.g.
row number 1: A1 B1 C1 ... AA1
row number 2: A2 B2 C2 ... AA2
etc.
To rule out mistakes like:
row number 1: A1 B1 C3 ... AA1
II.the formula in a column is similar over all rows, e.g.
in C1 the formula =A1*B1
in C2 the formula =A2*B2
etc.
To rule out mistakes like:
in C1 the formula =A1*D1
in C2 the formula =A2*B2*
To my amazement, I could not find any information about these important checks. I searched with many terms in different combination, e.g.
match compare index adjacent check error correct AND, OR and NOT functions etc.
Best and thanks in advance,
Roberto

How to calculate specific cards combination index

There are 22100 combinations of 3 cards from the 52 cards deck (52 * 51 * 50 / 3! = 22100).
Here is an enumeration of all these combinations:
static const ins cards_count = 52;
int boardId = 0;
for (int b1 = 0; b1 < card_count; b1++)
{
for (int b2 = b1 + 1; b2 < card_count; b2++)
{
for (int b3 = b2 + 1; b3 < card_count; b3++)
{
cout << boardId << endl;
boardId++;
}
}
}
Is it posssible to write an indexer fucntion that converts b1, b2, b3 to the boardId (without using a map)? If this is hard maybe you can advise some hash fucntion that maps b1, b2, b3 to the int size hash.
There is. It's pretty straightforward, too, and I briefly thought about writing down how, but then I realized I need quite a lot of mathematical notation for it.
The idea is to calculate how many combinations come before (or after) the one you need an index for.
The 3 from 52 combinations you state are correct, of course. Now let's enumerate how many come before b1,b2,b3:
First of all, there are all combinations with the first card smaller than b1. You have b1 options for the first card (since you start at 0), and for each of these options b1_, you have 52-b1_ choose 2 combinations. So, this number is the sum over b1_ from 0 to b1-1 over said binomial coefficient. With a little of math knowledge, you can derive a closed formula for that without actually evaluting a sum.
Second, there is all combinations with the first card having index b1 and the second card having index below b2. This is again a sum, but an easier one. You have one choice for the first card (b1) and b2-b1 (might be off by one, check that before you implement it) options for the second card. For each of these options (sum over b2_) you have 52-b2 options for the third card. This is a sum over consecutive numbers, and getting a closed formula for that is simple (hint: the sum of the first n numbers, starting at 1, is n*(n+1)/2, the sum of consecutive numbers not starting at one is the difference between two sums starting at 1).
Finally, you are interested in the number of combinations with the first two cards being b1 and b2 and the third being smaller than b3. This is simple, since that sum is exactly b3.
Only thing you need to do now is add the result from each item, and you have your index. I advise you take a piece of paper, do the math as proposed and get to a simple, easy to evaluate formula you can implement.
I would simply ignore the fact that cards in a set must be unique and sorted. Then your index is simply card1 + 52 * card2 + 52 * 52 * card3. With well formed sets not every index is reachable and the distribution is skewed towards lower numbers. Try hash = index % prime * 52 * 52 * 52 + index to even out the distribution. Try a low prime. The index part added ensures the hash will remain unique.
If you are only interested to assign and get the unique id of a set of any 3 different cards from a standard deck, there is no need to calculate the number of combinations for various set.
Let the cards in the deck be assigned with 1 to 52.
You could do it programatically as :
int getSetId (int card1, int card2, int card3){
if (card1 == card2 || card2 == card3 || card1 == card3)
//throw an exception
return (card1 * card2 * card3);
}
This will give you an unique id for all set combinations.
Edit 1:
In case there will be a duplicated id due to the multipliers forming the same product, instead of using 1 to 52, you can use the first 52 prime numbers.

Understanding Extended Euclid Algorithm

I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. The boxes are of two types:
Type 1: each box costs c1 Taka and can hold exactly n1 marbles
Type 2: each box costs c2 Taka and can hold exactly n2 marbles
I want each of the used boxes to be filled to its capacity and also to minimize the total cost of buying them. Since I find it difficult for me to figure out how to distribute my marbles among the boxes, I seek your help. I want your program to be efficient also.
Input
The input file may contain multiple test cases. Each test case begins with a line containing the integer n (1 <= n <= 2,000,000,000). The second line contains c1 and n1, and the third line contains c2 and n2. Here, c1, c2, n1 and n2 are all positive integers having values smaller than 2,000,000,000.
A test case containing a zero for n in the first line terminates the input.
Output
For each test case in the input print a line containing the minimum cost solution (two nonnegative integers m1 and m2, where mi = number of Type i boxes required) if one exists, print "failed" otherwise.
If a solution exists, you may assume that it is unique.
Sample Input
43
1 3
2 4
40
5 9
5 12
0
Sample Output
13 1
failed

Linear programming - combining models

(moved it here from math.se - it wasn't getting enough love out there. Sorry!)
So, I've been assigned with modeling a multi-processor setup using linear (integer) programming. Basically, there are five processors with links between them, and the goal is to find the optimal schedule of communication/processing as to minimize the time of processing a set amount of data. The graph is as follows:
---
|A|
---
|
|
--- ---
|B|----|D|
--- ---
| |
| |
--- ---
|C|----|E|
--- ---
with A being the data source. Now, there are a few different scenarios (related to the flow direction and the order of sending/receiving data), and for each scenario, the inequalities representing the processing time are different.
For example, if data flows from B to D, from B to C, from D to E, and from C to E, B communicates first with C, and then with D, and E receives first from C, and then from D, the total processing time for C is equal to:
Tc >= Cab + Cbc + Cce + Sc*Dc //Sc is constant
If, however, B sends data first to D, and then to C, then it's
Tc >= Cab + Cbd + Cbc + Cce + Sc*Dc //Sc is constant
And so on. Overall, there are 10 such scenarios, and for each one there's a couple of inequalities that need to be satisfied. What I need is a way to communicate to my solver "pick one of those sets of inequalities and don't mind about the rest". I presume I'll have to use some binary variables to encode those, I've also heard something about multiplying the variables by a huge value to "simulate" a conditional, but currently I can't find a way to "merge" all those mini-models into one and let the solver pick the best scenario.
Here's the sketch of the formulation:
You have ten scenarios, S1 through S10
Let's introduce binary variables Y_i which denotes which of the 10 scenarios is in play.
So these become a Specially Ordered Set :
Sum (over i in 1..10 ) Y_i = 1 (Only one scenario holds at a time.)
Requirement
For each scenario, there are a few inequalities that have to be obeyed. All other inequalities (applicable to other scenarios) should be ignored.
Let M be a big number. Say two orders of magnitude greater than the maximum possible processing time for any dataset.
Objective Function:
Min T
Constraints:
T >= Ta
...
T >= Tc
..
T >= Te
Let's use your scenario...Let's call it Scenario s. For each inequality that needs to be satisfied under scenario s, we introduce a M(1-Y_s) term to the LHS of the greater than inequality.
Inequalities for scenario s:
Tc + M(1-Y_s) >= Cab + Cbc + Cce + Sc*Dc //Sc is constant
Tc + M(1-Y_s) >= Cab + Cbd + Cbc + Cce + Sc*Dc //Sc is constant
...
...
Inequalities for some other scenario t:
Td + M(1-Y_t) >= Cde + Cbc + Sd*Dd //Sd is constant
Td + M(1-Y_t) >= Cde + Cbd + Cbc + Cce + Sd*Dd //Sd is constant
..
Inequalities for scenario u:
...
...
and so on.
Depending on whichever Y_i is 1, those M(1-Y_i) terms will become zero. So the inequalities will be enforced.
For all the M(1-Y_j)..The left hand side will be a huge number, and the inequality will be always hold trivially.
The nice thing is that since the overall objective is to minimize T, which in turn is the max of Ta...Te...over all 10 scenarios, the Solver will automatically pick the most optimal scenario.
Hope that helps.

Efficient access matrix columns

Efficient access question: I need to access a large matrix (more than 2000x2000) column wise, my algorithm require a 1 row pass and 1 column pass. Row pass is fine for memory efficiency (cache miss), but how to reduce the cache miss in the column pass? I need efficiency.
The only thing I had in my is like : declare n local variable (based on memory fetch size),
int a1, a2, a3, a4;
for ( int j = 0 ; j < DIM_Y ; j+=4 ) for ( int i = 0 ; i < DIM_X ; i++ )
a1 = matrix[i][j]; ... ; a4 = matrix[i][j+4];
// make the column processing on the 4 variables.
It's in C or C++, and array or int or char.
Any proposition and comment is welcomed.
Thanks.
Two basic techniques apply:
1) loop blocking
Instead of
for (j=0;j<2000;j++)
for (i=0;i<2000;i++)
process_element(i,j);
use
for (j=0;j<2000;j+=8)
for (i=0;i<2000;i+=8)
process_block_of_8x8(i,j);
2) non-power of 2 row stride (e.g. 8192 bytes + 64) -- pad if necessary
in this case row[i] .. row[i+7] will not fight for the same cache line
the data should be in continuous memory region with the manually calculated padding.
The efficient way to store a 2D matrix, is using a C style array like this:
| a11 a12 a13 |
| a21 a22 a23 | -> memory: [a11,a12,a13,a21,a22,a23,a31,a32,a33]
| a31 a32 a33 |
Element(i,j) = memory[N_COL*i+j]
where i is the row number index starting from 0, and j the column number index also starting from 0, and N_COL the number of columns.
Hopefully the compiler/jit is going to place all the values sequentially in memory for quick access. Usually the more you are trying to trick the compiler (like manual loop unrolling) the more you hurt yourself in performance. Write clean code and let the compiler do its thing.