private void makeSwarmMotion() {

		iteration++;

		double w;
		if (iteration > linWeightTreshold) {

			w = linWeightEnd;

		} else {

			w = linWeightStart + (linWeightEnd-linWeightStart)*
					(iteration-1.0)/linWeightTreshold;

		}

		neighborhood.scan(particles);

		for (int i = 0; i < particles.length; i++) {

			//find best neighborhood solution
			int[] socialBest = neighborhood.findBest(i);

			for (int d = 0; d < dimension; d++) {

				particles[i].setPreviousWorkUnitIndexes(
						d, particles[i].getProjectWorkUnitIndexes()[d]);

				//COMPUTE VELOCITY
				//IN THIS PROJECT VELOCITY = PROBABILITY OF VECTOR POSITION MUTATION

				double velocity = 
						w*particles[i].getVelocity()[d] +
						c1*rand.nextDouble() * (
								particles[i].getBestWorkUnitIndexes()[d] - 
								particles[i].getProjectWorkUnitIndexes()[d]
								) +
								c2*rand.nextDouble() * (
										socialBest[d] - 
										particles[i].getProjectWorkUnitIndexes()[d]
										);

				//increase or decrease velocity
				velocity *= γ;

				//1-Math.pow(Math.E, -Math.abs(velocity)) => velocity limited to interval [0,1]
				particles[i].setVelocity(d, 1-Math.pow(Math.E, -Math.abs(velocity)));

				if (particles[i].getVelocity()[d] < -velBounds[d]) {

					particles[i].setVelocity(d, -velBounds[d]);

				} else if (particles[i].getVelocity()[d] > velBounds[d]) {

					particles[i].setVelocity(d, velBounds[d]);
				}

			}

			//PARTICLE UPDATE POSITION
			particles[i].moveParticle(rand);

		}

		//set particle local best position
		for (int i = 0; i < particles.length; i++) {

			particles[i].evaluate();

			if (particles[i].getActualDuration() < 
					particles[i].getBestProjectDuration()) {

				particles[i].setBestProjectDuration(
						particles[i].getActualDuration()
						);

				particles[i].setBestWorkUnitIndexes(
						particles[i].getProjectWorkUnitIndexes()
						);

			}

		}

	}