Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving Pheromone Update Performance #3

Open
Barbapoulpe opened this issue Jul 9, 2018 · 2 comments
Open

Improving Pheromone Update Performance #3

Barbapoulpe opened this issue Jul 9, 2018 · 2 comments

Comments

@Barbapoulpe
Copy link

Barbapoulpe commented Jul 9, 2018

The pheromone update has quite poor performance as it is now because it loops on the graph matrix (O(n²)), then for each cell (edge), it loops over each ant (potentially O(n) since most papers use a number of ants similar or equal to the number of cities).
An easy improvement would be to treat the evaporation and depositing separately.
for Deposits: loop over the ants and their path (O(n²)) directly depositing the pheromones on the path (O(1))
for Evaporation: loop over the matrix only (O(n²))
Further improvement would be to have those run in parallel (parallelization of the evaporation is quite simple as there should be no racing conflicts but for the deposits a locking mechanism on the edges would be necessary as several ants can use the same edge in their paths)

@Barbapoulpe
Copy link
Author

Barbapoulpe commented Jul 9, 2018

public class ImprovedPartialDeposit extends PartialDeposit{
        private int resetValue;
	double[][] deposits;
	public ImprovedPartialDeposit(ACO aco, double rate, AbstractSubSet subSet) {
		super(aco, rate, subSet);
		this.deposits=new double[aco.getProblem().getNumberOfNodes()] [aco.getProblem().getNumberOfNodes()];
                resetValue=aco.getProblem().getNumberOfNodes();

	}
	private void resetPheromones() {
		for(int i=0; i<deposits.length;i++) {
			for(int j=0;j<deposits[i].length;j++) {
				deposits[i][j]=0;
			}
		}
		calcDeposits();
	}
	public double getTheNewValue(int i, int j) {
		if(i<resetValue) resetPheromones();
		resetValue=i;
		return aco.getGraph().getTau(i, j) + rate * deposits[i][j];
		
	}
	private void calcDeposits() {
		int nNodes=aco.getProblem().getNumberOfNodes();
		for(Ant a: subSet.getSubSet()) {
			for(int k=0;k<nNodes;k++) {
				int i=a.getSolution()[k];
				int j=a.getSolution()[(k+1)%nNodes];
				double deltaTau=aco.getProblem().getDeltaTau(a.getTourLength(), i, j);
				if(a.path[i][j]==1) {
					deposits[i][j]+= deltaTau;
				}
				if(a.path[j][i]==1) {
					deposits[j][i]+= deltaTau;
				}
			}
		}
	}
} 

seems to work with minimal change to the code and improves the run time drastically (tested on a280.tsp).

Edit: fixed formatting of code and now correctly uses only the ants from the subset
Edit2: now supports asymetric TSP

@Barbapoulpe
Copy link
Author

Barbapoulpe commented Jul 10, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant