Cluster analysis

For AI and campaign script related discussions and questions
Post Reply
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Cluster analysis

Post 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;
	}
}
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Cluster analysis

Post 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?
}
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Cluster analysis

Post 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.
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Cluster analysis

Post 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.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Cluster analysis

Post 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.
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Cluster analysis

Post 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.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Cluster analysis

Post 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.
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Cluster analysis

Post 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.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Cluster analysis

Post 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 :3
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Cluster analysis

Post 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.
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Cluster analysis

Post 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).
User avatar
Iluvalar
Regular
Regular
Posts: 1828
Joined: 02 Oct 2010, 18:44

Re: Cluster analysis

Post 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. :lol2:
Heretic 2.3 improver and proud of it.
User avatar
Shadow Wolf TJC
Regular
Regular
Posts: 1047
Joined: 16 Apr 2011, 05:12
Location: Raleigh, NC

Re: Cluster analysis

Post 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 2r from them, where r is the max distance from the center of the cluster. (The reason why I said 2r 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. :wink:
Creator of Warzone 2100: Contingency!
Founder of Wikizone 2100: http://wikizone2100.wikia.com/wiki/Wikizone_2100
User avatar
aubergine
Professional
Professional
Posts: 3459
Joined: 10 Oct 2010, 00:58
Contact:

Re: Cluster analysis

Post by aubergine »

Was looking through the wz source code and spotted this which may be of use:
https://github.com/Warzone2100/warzone2 ... luster.cpp
"Dedicated to discovering Warzone artefacts, and sharing them freely for the benefit of the community."
-- https://warzone.atlassian.net/wiki/display/GO
Post Reply