Page 1 of 1
Cluster analysis
Posted: 07 Feb 2012, 10:09
by NoQ
It is often useful to know if your units are grouped or scattered, and what is the easiest way to get them grouped. Cluster analysis seems to be the right tool for this, but i have no idea how it works or which of its algorithms are suitable for the situation.
So far i have only come up with the following code. We suppose we have a "
list" array that is filled with objects that have "
.x" and "
.y" properties; a list of droids is a good example. The following code splits it into a 2d array called "
clusters", so that each
clusters[j] is grouped in the following sense: the distance of any of its elements from its mass center (
xav[j],
yav[j]) is less than
MAX_DISTANCE. It seems to work at O(n^2), where n is the length of the list.
Can this be improved?
Code: Select all
clusters=[];
xav=[];
yav=[];
for (i=list.length-1; i>=0; --i) {
var x=list[i].x,y=list[i].y;
var found=false;
for (var j=0; j<clusters.length; ++j) {
if (distBetweenTwoPoints(xav[j],yav[j],x,y)<MAX_DISTANCE) {
var n=clusters[j].length;
clusters[j][n]=i;
xav[j]=(n*xav[j]+x)/(n+1);
yav[j]=(n*yav[j]+y)/(n+1);
found=true;
break;
}
}
if (!found) {
var n=clusters.length;
clusters[n]=[i];
xav[n]=x;
yav[n]=y;
}
}
Re: Cluster analysis
Posted: 07 Feb 2012, 11:20
by aubergine
If checking your own units, assuming they are in a group, could you not do something like:
Code: Select all
var x1,y1,x2,y2;
x1 = y1 = Number.MAX_VALUE;
x2 = y2 = Number.MIN_VALUE;
var droids = enumGroup(someGroup);
var i = droids.length;
while (-1<--i) {
// calc A point = top-left
x1 = Math.min(x1,droids[i].x);
y1 = Math.min(y1,droids[i].y);
// calc B point = bottom-right
x2 = Math.max(x2,droids[i].x);
y2 = Math.max(y2,droids[i].y);
// prolly want to work out average position of droids here as well
}
var dist = distBetweenTwoPoints(x1,y1,x2,y2);
if (dist > maxRegroupDist) {
// the droids are too far apart, probably taking different routes round map
// don't bother regrouping them
} else if (dist < minRegroupDist) {
// they are close enough already
// don't bother regrouping them
} else {
// regroup them to average droid position?
}
Re: Cluster analysis
Posted: 07 Feb 2012, 11:56
by NoQ
This is pretty close to what i have used to far, and you have already seen how horrible the results are.
If there are 20 units around (100,100) (enemy base) and one unit at (0,0) (just produced at your own base), all 20 units have to retreat and fall back to meet the lonely unit at (0,0). That's the exact reason of unit dancing.
I have tried to calculate the mass center and move only units that are too far from it, but this didn't help too much (as the mass center quickly moves towards the middle as tanks are produced.
So the only way here is to split the group into clusters, find the biggest cluster, and move all other clusters towards it.
That's why i'm looking for an effective and cpu-effective way of splitting groups into clusters.
Re: Cluster analysis
Posted: 07 Feb 2012, 12:20
by aubergine
That's why I include the maxRegroupDist check - so if there are some units far outside the group, you just don't bother regrouping.
Assuming that the regroup check happens every 10 seconds or so, the group should never get too dispersed.
And, when a droid gets destroyed, causing a new one at your base to be added to group, the group won't bother regrouping just to get that lonesome droid in to the fold.
Re: Cluster analysis
Posted: 07 Feb 2012, 12:27
by NoQ
aubergine wrote:And, when a droid gets destroyed, causing a new one at your base to be added to group, the group won't bother regrouping just to get that lonesome droid in to the fold.
Yeah, i missed that point. Anyway, if units come out every minute, and the map rush distances are around two minutes, the group will
never be regrouped. And even if this is not the case, the group will start dancing as soon as the new unit is in range.
Re: Cluster analysis
Posted: 07 Feb 2012, 12:49
by aubergine
So, maybe give it a try anyway and see what happens in practice?
Fiddling with min/maxRegroupDist should allow fine tuning.
EDIT: Also, avoid making the group too bunched up (ie. minRegroupDist should prolly be something like 400) otherwise they will spend too much time dithering = artillery fodder.
Re: Cluster analysis
Posted: 07 Feb 2012, 12:58
by NoQ
ie. minRegroupDist should prolly be something like 400
That sounds like something bigger than any map supported by the game ...
So, maybe give it a try anyway and see what happens in practice?
the group will never be regrouped
, i guess ...
Anyway, with clustering method mentioned above, i'm having much better results already. So i'd really prefer to keep this thread for comparing different clustering methods only, and not for discussing wether the clusterisation itself is effective ... please.
Re: Cluster analysis
Posted: 07 Feb 2012, 13:00
by aubergine
400 = 400 pixels, not tiles. 128 pixels per tile.
With regards to your cluster method at start of this topic, the issue is that it's doing lots of iterations through droids. My approach (which I've not tested) only makes 1 pass through the list of droids.
Re: Cluster analysis
Posted: 07 Feb 2012, 13:16
by NoQ
aubergine wrote:400 = 400 pixels, not tiles. 128 pixels per tile.
Ok then (: Sounds like too small now. I'm using 5 tiles +1 per every 10 units in group (otherwise the group might get regrouping forever ...)
aubergine wrote:With regards to your cluster method at start of this topic, the issue is that it's doing lots of iterations through droids. My approach (which I've not tested) only makes 1 pass through the list of droids.
Yeah, that's why i asked ... i don't want to give up the idea itself just because that particular implementation is slow

Re: Cluster analysis
Posted: 07 Feb 2012, 14:14
by aubergine
I think your clustering approach is better suited to clustering enemy units / structures.
For example, when doing a laser strike you could cluster enemy object based on size of a laser strike, then work out which cluster has the most buildings/droids in, etc.
Re: Cluster analysis
Posted: 07 Feb 2012, 14:16
by NoQ
Agreed; even though laser satellite strikes are a pretty rare thing, some tactics can be built on top of it (eg., if my cluster is smaller than yours, i should run).
Re: Cluster analysis
Posted: 07 Feb 2012, 20:32
by Iluvalar
NoQ wrote:
I have tried to calculate the mass center and move only units that are too far from it, but this didn't help too much (as the mass center quickly moves towards the middle as tanks are produced.
Reduce the dimension of the distance. SquareRoot the distances ! Or whatever dimension lesser than 1 seem to fit. This way bigger distance will be neglected more than smaller distance when you calculate the "center". I think it will become a center of gravity forces, but don't quote me on that.

Re: Cluster analysis
Posted: 09 Feb 2012, 01:00
by Shadow Wolf TJC
I personally don't know how to code for this game yet, but I do have a basic idea on where to start in order to solve this kind of problem.
1. Have each unit that belongs in a cluster perform a check on each of its "comrades" to see if any of them are more than distance 2
r from them, where
r is the max distance from the center of the cluster. (The reason why I said 2
r is because some units within the cluster would probably lie on opposite ends of the circle, and would, thus, be, at the very most, twice the length of radius r away.)
2. If any of its comrades do fall beyond this range, then add +1 to counter
NoOfDistantComrades (or whatever you'd like to name it), add each of the distant comrades' x-coordinates up to create
SumX, add each of the distant comrades' y-coordinates up to create
SumY, then finally, divide
SumX by
NoOfDistantComrades, and divide
SumY by
NoOfDistantComrades, and you'll get the x-y-coordinates for where your unit needs to go in order to reunite with them.
If need be, you can perform this check once every few seconds.

Re: Cluster analysis
Posted: 15 Feb 2012, 00:28
by aubergine
Was looking through the wz source code and spotted this which may be of use:
https://github.com/Warzone2100/warzone2 ... luster.cpp