I
I
ireader2022-02-20 19:04:59
Algorithms
ireader, 2022-02-20 19:04:59

How to generate the most diverse combinations from the elements of a given set of sets?

The task of generating sprites to form a landscape tileset.

Given a number of basic sprites, which are distributed over several layers. To generate one tile, we need to take one of any sprite from each layer and sequentially overlay them on top of each other. 

For example:
1st layer: Sea/Coast/Land
2nd layer: Rocks
3rd layer: Peak/plateau
4th layer: Grass
5th layer: Decorative elements

The number of sprites in each layer is arbitrary, but can only be within [1..16]
Number into layers also arbitrarily, but within [1..6]

You need to get 16 or fewer (if more cannot be generated) unique tiles, consisting of as many different combinations of original sprites as possible - i.e. the less they or their combinations are repeated for different tiles, the better. 

Example:

spoiler

для 
{{0, 1, 2}, - слой 1
 {0, 1, 2}, - слой 2
 {0, 1, 2}} - слой 3

Результат  будет примерно таким:
0 0 0
1 1 1
2 2 2
0 1 2
1 2 0
2 0 1
0 2 1
1 0 2
2 1 0
0 0 1
1 1 2
2 2 0
0 1 0
1 2 1
2 0 2
0 0 2

It seems to me that there are 2 ways to solve this problem:

1. Each layer, in fact, is a one-dimensional set. To obtain all possible combinations, it is enough for us to perform a direct (Cartesian) product of these sets. And sort the resulting sets by "diversity". 
But in this case there are 2 difficulties:
  1. There can be quite a lot of combinations (we only need 16 of them).
  2. Compare not only the sets themselves with each other, but also with those already selected, for the frequency of repetition of the combinations included in them.

2. Immediately generate the most diverse combinations.

I have to admit that I'm stuck on both options - in the first on the sorting algorithm, in the second on the generation algorithm. Please help or advice.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
N
Nikolay Savelyev, 2022-02-20
@ireader

Here is a good old article on this topic https://habr.com/ru/post/117160/

W
Wataru, 2022-02-20
@wataru

I see the following algorithm:
First, if you can generate less than 16 sprites in total, then just generate them all.
Next, we will generate all 16 sprites at once. The current sprites will have the first K layers filled and grouped into line segments by coincidence. Further, for each segment of length L, if L is greater than the number of options in the current layer (N), then break the segment into N pieces of approximately the same length. All chunks will be floor(L/N) long and L%N of them will be 1 longer. If L < N, then randomly choose L sprites in the current layer and get a bunch of segments of length 1.
For more randomness, you can mix the layers before generation and process them in random order.

A
Alexandroppolus, 2022-02-20
@Alexandroppolus

Randomly shuffle each of the arrays - https://qna.habr.com/q/1118198
and then take combinations: (a[0], b[0], ..., f[0]), (a[1] , b[1], ..., f[1]), ...
where a, b.. - layers
if, say, N tiles are needed, and there are only M options in the layer, where M < N, then from this layer (mixed) we can take the element with the index (i % M)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question