How to re-order units based on their degree of desirable neighborhood ? (in Processing) How to re-order units based on their degree of desirable neighborhood ? (in Processing) python python

How to re-order units based on their degree of desirable neighborhood ? (in Processing)


The solution I propose to solve this challenge is based on repeating the algorithm several times while recordig valid solutions. As solution is not unique, I expect the algorithm to throw more than 1 solution. Each of them will have a score based on neighbours affinity.

I'll call an 'attempt' to a complete run trying to find a valid plant distribution. Full script run will consist in N attempts.

Each attempt starts with 2 random (uniform) choices:

  • Starting point in grid
  • Starting office

Once defined a point and an office, it comes an 'expansion process' trying to fit all the office blocks into the grid.

Each new block is set according to his procedure:

  • 1st. Compute affinity for each adjacent cell to the office.
  • 2nd. Randomly select one site. Choices should be weighted by the affinity.

After every office block is placed, another uniform random choice is needed: next office to be placed.

Once picked, you should compute again affinitty for each site, and randomly (weigthed) select the starting point for the new office.

0 affinity offices don't add. Probability factor should be 0 for that point in the grid. Affinity function selection is an iteresting part of this problem. You could try with the addition or even the multiplication of adjacent cells factor.

Expansion process takes part again until every block of the office is placed.

So basically, office picking follows a uniform distribution and, after that, the weighted expansion process happens for selected office.

When does an attempt end?, If:

  • There's no point in grid to place a new office (all have affinity = 0)
  • Office can't expand because all affinity weights equal 0

Then the attempt is not valid and should be descarded moving to a fully new random attempt.

Otherwise, if all blocks are fit: it's valid.

The point is that offices should stick together. That's the key point of the algorithm, which randomly tries to fit every new office according to affinity but still a random process. If conditions are not met (not valid), the random process starts again choosing a newly random gridpoint and office.

enter image description here

Sorry there's just an algorithm but nothing of code here.

Note: I'm sure the affinity compute process could be improved or even you could try with some different methods. This is just an idea to help you get your solution.

Hope it helps.


I'm sure the Professor Kostas Terzidis would be an excellent computer theory researcher, but his algorithm explanations don't help at all.

First, the adjacency matrix has no sense. In the questions comments you said:

"the higher that value is, the higher the probability that the two spaces are adjecent is"

but m[i][i] = 0, so that means people in the same "office" prefer other offices as neighbor. That's exactly the opposite that you'd expect, isn't it? I suggest to use this matrix instead:

With 1 <= i, j <= 5:              +----------------+              | 10  6  1  5  2 |              |    10  1  4  0 |    m[i][j] = |       10  8  0 |                |          10  3 |              |             10 |              +----------------+

With this matrix,

  • The highest value is 10. So m[i][i] = 10 means exactly what you want: People in the same office should be together.
  • The lowest value is 0. (People who shouldn't have any contact at all)

The algorithm

Step 1: Start putting all places randomly

(So sorry for 1-based matrix indexing, but it's to be consistent with adjacency matrix.)

With 1 <= x <= 5 and 1 <= y <= 7:            +---------------------+            | -  -  1  2  1  4  3 |            | 1  2  4  5  1  4  3 |  p[x][y] = | 2  4  2  4  3  2  4 |            | -  -  -  -  3  2  4 |            | -  -  -  -  5  3  3 |            +---------------------+

Step 2: Score the solution

For all places p[x][y], calculate the score using the adjacency matrix. For example, the first place 1 has 2 and 4 as neighbors, so the score is 11:

score(p[1][3]) = m[1][2] + m[1][4] = 11

The sum of all individual scores would be the solution score.

Step 3: Refine the current solution by swapping places

For each pair of places p[x1][y1], p[x2][y2], swap them and evaluate the solution again, if the score is better, keep the new solution. In any case repeat the step 3 till no permutation is able to improve the solution.

For example, if you swap p[1][4] with p[2][1]:

            +---------------------+            | -  -  1  1  1  4  3 |            | 2  2  4  5  1  4  3 |  p[x][y] = | 2  4  2  4  3  2  4 |            | -  -  -  -  3  2  4 |            | -  -  -  -  5  3  3 |            +---------------------+

you'll find a solution with a better score:

before swap

score(p[1][3]) = m[1][2] + m[1][4] = 11score(p[2][1]) = m[1][2] + m[1][2] = 12

after swap

score(p[1][3]) = m[1][1] + m[1][4] = 15score(p[2][1]) = m[2][2] + m[2][2] = 20

So keep it and continue swapping places.

Some notes

  • Notice the algorithm will always finalize given that at some point of the iteration you won't be able to swap 2 places and have a better score.
  • In a matrix with N places there are N x (N-1) possible swaps, and that can be done in a efficient way (so, no brute force is needed).

Hope it helps!