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

Add farthest-insertion algorithm for the TSP #1105

Merged
merged 8 commits into from Mar 22, 2024

Conversation

alex-cornejo
Copy link

@alex-cornejo alex-cornejo commented Sep 6, 2021

Issue: #1104.
Add an implementation of the farthest-insertion heuristic for the Traveling Salesman Problem (TSP).

For the purpose of coding this algorithm with good quality, this implementation takes some performance ideas from other algorithm implementations such as NearhestInsertionTSP, NearhestNeighborTSP, and FloydWharsall.

This implementation has a similar structure to other algorithms implementations for the TSP already implemented in jGrapht.

According to some references and experimentation I performed, in several cases, this algorithm outperforms the others regarding running time and quality of found solutions.

Please see the linked issue #1104 to check additional details and a small comparison I performed.

Some references:

  • D. Rosenkrantz, R. Stearns, and P. II, "An analysis of several heuristics for the traveling salesman problem," SIAM J. Comput., vol. 6, pp. 563{581, 09 1977.
  • Skiena, S.-S. (2020). The Algorithm Design Manual (3rd ed.). Springer International Publishing.

@alex-cornejo
Copy link
Author

Any interest in this?

@micycle1
Copy link

It's rather good. Images below compare farthest-insertion vs nearest-neighbour. It's ~3x faster with a better result too!

image

image

@alex-cornejo
Copy link
Author

alex-cornejo commented Jan 7, 2024

@jkinable any interest on this?

@syoon2
Copy link

syoon2 commented Mar 17, 2024

Just FYI - the tests would not "run" after merging because JGraphT now uses JUnit 5 and your tests are written in JUnit 4.
By looking at your tests it seems that it would be as simple as replacing the JUnit 4 imports with the JUnit 5 equivalents though.

Edit: After taking a closer look, some tests require more than just editing the imports; specifically, the expected attribute is no longer supported in JUnit 5's @Test annotation.

@alex-cornejo
Copy link
Author

It's rather good. Images below compare farthest-insertion vs nearest-neighbour. It's ~3x faster with a better result too!

image

image

Did you use a software to plot these tours?

@alex-cornejo
Copy link
Author

alex-cornejo commented Mar 17, 2024

Just FYI - the tests would not "run" after merging because JGraphT now uses JUnit 5 and your tests are written in JUnit 4. By looking at your tests it seems that it would be as simple as replacing the JUnit 4 imports with the JUnit 5 equivalents though.

Thanks so much for the observation. I can update the PR for JUnit 5; nevertheless, before any effort, it would be great to know if the JGrapht team is interested in integrating this PR since it has not been merged for a long time, maybe because it is not of interest.
@jkinable

UPDATE
I updated the unit tests to jUnit5.

@syoon2
Copy link

syoon2 commented Mar 17, 2024

@jsichi would you mind taking a look?

Previous implementation was based on the jgrapht implementation of Nearest Neighbor. Now it was changed and now is based on Nearest Insertion.
@micycle1
Copy link

It's rather good. Images below compare farthest-insertion vs nearest-neighbour. It's ~3x faster with a better result too!
image
image

Did you use a software to plot these tours?

My own software that uses Processing for graphics.

Copy link
Member

@jsichi jsichi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your incredible patience! I will merge this after the swap methods are made private.

* @param i the index of the first element
* @param j the index of the second element
*/
public static void swap(double[] arr, int i, int j)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this private

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about moving the swap methods to the org.jgrapht.util.ArrayUtil class?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's better!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for your feedback. Done.

* @param i the index of the first element
* @param j the index of the second element
*/
public static void swap(int[] arr, int i, int j)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one too.

Copy link

@syoon2 syoon2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just few documentation stuff that came up to me while reading the changes:

  • I think that @since tags should be added to Javadoc for the new classes / methods (see suggestions)
  • I don't think the license headers for the two new files are accurate? It isn't 2021 now for sure...

Disclaimer: I am not associated with the maintainer(s) of the JGraphT repository, nor do I claim to be.

Comment on lines 71 to 74
* @param <V> the graph vertex type
* @param <E> the graph edge type
* @author José Alejandro Cornejo Acosta
*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param <V> the graph vertex type
* @param <E> the graph edge type
* @author José Alejandro Cornejo Acosta
*/
* @param <V> the graph vertex type
* @param <E> the graph edge type
* @author José Alejandro Cornejo Acosta
*
* @since 1.5.3
*/

Comment on lines 32 to 36
/**
* Unit tests for the {@link FarthestInsertionHeuristicTSP}
*
* @author Jose Alejandro Cornejo Acosta
*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* Unit tests for the {@link FarthestInsertionHeuristicTSP}
*
* @author Jose Alejandro Cornejo Acosta
*/
/**
* Unit tests for the {@link FarthestInsertionHeuristicTSP}
*
* @author Jose Alejandro Cornejo Acosta
*
* @since 1.5.3
*/

jgrapht-core/src/main/java/org/jgrapht/util/ArrayUtil.java Outdated Show resolved Hide resolved
jgrapht-core/src/main/java/org/jgrapht/util/ArrayUtil.java Outdated Show resolved Hide resolved
@alex-cornejo
Copy link
Author

alex-cornejo commented Mar 22, 2024

Just few documentation stuff that came up to me while reading the changes:

* I think that `@since` tags should be added to Javadoc for the new classes / methods (see suggestions)

* I don't think the license headers for the two new files are accurate? It isn't 2021 now for sure...

Disclaimer: I am not associated with the maintainer(s) of the JGraphT repository, nor do I claim to be.

Interesting. I agree with you about the dates. Let's

Just few documentation stuff that came up to me while reading the changes:

* I think that `@since` tags should be added to Javadoc for the new classes / methods (see suggestions)

* I don't think the license headers for the two new files are accurate? It isn't 2021 now for sure...

Disclaimer: I am not associated with the maintainer(s) of the JGraphT repository, nor do I claim to be.

Interesting. I agree with you about the dates, but the instructions say not to change the header. @jsichi What do you think about it?

@jsichi
Copy link
Member

jsichi commented Mar 22, 2024

As it says in:

https://github.com/jgrapht/jgrapht/wiki/Dev-guide%3A-How-to-make-your-first-(code)-contribution

The only modifications you are allowed to make to the header are the year, and your name on the first line. The first line of the header should read:
* (C) Copyright <current year>-<current year>, by <your name> and Contributors.

Since these are new files, you should use your name (instead of copying the names from other files). For the year range, you can put 2021-2024 due to the long review period.

Thanks @syoon2 for noticing that.

@alex-cornejo
Copy link
Author

As it says in:

https://github.com/jgrapht/jgrapht/wiki/Dev-guide%3A-How-to-make-your-first-(code)-contribution

The only modifications you are allowed to make to the header are the year, and your name on the first line. The first line of the header should read: * (C) Copyright <current year>-<current year>, by <your name> and Contributors.

Since these are new files, you should use your name (instead of copying the names from other files). For the year range, you can put 2021-2024 due to the long review period.

Thanks @syoon2 for noticing that.

I updated the headers. Thanks so much for the observation.

Co-authored-by: Sung Ho Yoon <55358516+syoon2@users.noreply.github.com>
@jsichi
Copy link
Member

jsichi commented Mar 22, 2024

Thanks!

@jsichi jsichi merged commit 5e72248 into jgrapht:master Mar 22, 2024
3 checks passed
@alex-cornejo alex-cornejo deleted the farthest-insertion branch March 24, 2024 01:55
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

Successfully merging this pull request may close these issues.

None yet

4 participants