public List<SampleData> run() { init(); for (int c = 0; c < ITERATION_COUNT; c++) { List<Boid> newBoids = new ArrayList<>(); for (int bid = 0; bid < boids.size(); bid++) { Boid b = boids.get(bid); int localCount = 0; Velocity varTotal = new Velocity(0, 0); // alignment Velocity vsr = new Velocity(0, 0); // separation Velocity vcr = new Velocity(0, 0); // cohesion Velocity vds = new Velocity(0, 0); // similarity Velocity vdd = new Velocity(0, 0); // dissimilarity for (int xid = 0; xid < boids.size(); xid++) { Boid x = boids.get(xid); double d = getDistance(b, x); if (d > SENSE_RANGE) { continue; } varTotal.vx += x.v.vx; varTotal.vy += x.v.vy; vsr.vx += d == 0 ? 0 : (x.v.vx + b.v.vx) / d; vsr.vy += d == 0 ? 0 : (x.v.vy + b.v.vy) / d; vcr.vx += x.x - b.x; vcr.vy += x.y - b.y; double sim = computeSimilarity(xid, bid); vds.vx += sim * d * x.v.vx; vds.vy += sim * d * x.v.vy; vdd.vx += sim * d == 0 ? 0 : (1 / (sim * d)) * x.v.vx; vdd.vy += sim * d == 0 ? 0 : (1 / (sim * d)) * x.v.vy; localCount++; } Velocity var = localCount == 0 ? new Velocity(0, 0) : new Velocity(varTotal.vx / localCount, varTotal.vy / localCount); // compute updated weighted velocity for b Velocity newV = updateVelocity(var, vsr, vcr, vds, vdd); newBoids.add(new Boid(newV, b.x - newV.vx, newV.vy)); } boids = newBoids; } // update dataset List<SampleData> points = new ArrayList<>(); for (int i = 0; i < boids.size(); i++) { List<Double> attributes = new ArrayList<>(); attributes.add(boids.get(i).x); attributes.add(boids.get(i).y); SampleData sd = new SampleData(attributes, i); points.add(sd); } return points; }