0

I figure I have the general idea down for how to solve the algorithm but the implementation seems to elude me. What I have thus far is this:

public class GreedySalesman {


public static int[] greedySalesmanSolution(int[][] distances) {
    List cityList = new ArrayList();
            for(int[] array: distances) {
               cityList.add(Arrays.asList(array));
            }
    List<Integer> initialResult = new ArrayList();
    initialResult.add(0);
    List<Integer> finalResult = findMinDistance(cityList, cityList, initialResult, 0);
          /*int finalResultArray = new int[finalResult.size()+1];
    int i = 0;
    while (!(finalResult.isEmpty)) {
                finalResultArray[i] = finalResult.poll();
                i++;
    }

    return finalResultArray;
    */
          return null;
        }

public static List<Integer> findMinDistance(List<List<Integer>> initialCityInput, List<List<Integer>> cityInput, List<Integer> distanceResult, int index) {
        if(cityInput.isEmpty()) {
            distanceResult.add(0);
            return distanceResult;
        }
        int min = Collections.min(initialCityInput.get(index));
        List<Integer> city = initialCityInput.get(index);
        index = city.indexOf(min);
        distanceResult.add(index);
        cityInput.remove(city);

        return findMinDistance(initialCityInput,cityInput,distanceResult,index);

}
}

That is, the algorithm will take an two dimensional array of ints as an input, then make a List cityList referring to distances, then pass it into findMinDistance. The commented out part is where the result from findMinDistance will be converted into an array of ints and returned as finalResultArray but that part is not important yet.

findMinDistance will take in a two dimensional list of Integers twice, a List of Integers that will become the result and an int representing an index. The function will return the distanceResult when cityInput has been emptied. Otherwise it will start with the first city based on the index, get the minimum distance from that List and its index and add the index to the distanceResult. Once that has been done, the city will be removed from the cityInput and the program will go into recursion until cityInput has been emptied.

The issue I am getting currently is I cannot be cast to java.lang.Integer at

int min = Collections.min(initialCityInput.get(index));

And in main upon trying to run the program with some test data. Any help will be appreciated.

======

Edit:

I made some changes to my code

public class GreedyTSP {

    public int[] greedySalesmanSolution(int[][] distances) {
                List<List<Integer>> cityList = new ArrayList();
                List<List<Integer>> initialCityList = new ArrayList();
                int iLength = distances.length;
                for (int i = 0; i < iLength; ++i) {
                    int jLength = distances[0].length;
                    cityList.add(new ArrayList(jLength));
                    initialCityList.add(new ArrayList(jLength));
                    for (int j = 0; j < jLength; ++j) {
                      cityList.get(i).add(distances[i][j]);
                      initialCityList.get(i).add(distances[i][j]);
                    }
                }

        List<Integer> initialResult = new ArrayList();
        initialResult.add(0);
        List<Integer> finalResult = findMinDistance(initialCityList, cityList, initialResult, 0);
                int[] finalResultArray = new int[finalResult.size()];
                Iterator<Integer> iterator = finalResult.iterator();
                for (int i = 0; i < finalResultArray.length; i++){
                    finalResultArray[i] = iterator.next().intValue();
                }
        return finalResultArray;


            }

        public List<Integer> findMinDistance(List<List<Integer>> initialCityInput, List<List<Integer>> cityInput, List<Integer> distanceResult, int initialIndex) {
            if(cityInput.isEmpty()) {
                distanceResult.add(0);
                return distanceResult;
            }  
            List<Integer> city = initialCityInput.get(initialIndex);
            Integer min = findMin(city, distanceResult, initialIndex);
            int resultIndex = city.indexOf(min);
            distanceResult.add(resultIndex);
            cityInput.remove(city);
            return findMinDistance(initialCityInput,cityInput,distanceResult,resultIndex);
    }

        public Integer findMin(List<Integer> city, List<Integer> distanceResult, int inputIndex) {
            Integer min = Integer.MAX_VALUE;
            for(int i = 0; i < city.size();i++) {
                if (city.get(i) > inputIndex && city.get(i) < min) min = city.get(i);
            }
            int resultIndex = city.indexOf(min);
            if(distanceResult.contains(resultIndex)) {
                return findMin(city, distanceResult, inputIndex);
            }

            return min;
        }   
}

Im not having any cast errors at the moment but it seems that the parts of my program dealing with recursion are causing StackOverflowError-s. I've been messing with this thing for literally 16 hours now and I'm all out of ideas as to why. Any ideas?

T44v1
  • 157
  • 1
  • 1
  • 9

2 Answers2

0

The problem with your casting is the following

List<List<Integer>> initialCityInput is a List containing Lists with integers.

Therefore initalCityInput.get(index) returns a List not an Int, which cannot be cast to int.

Stefan
  • 2,098
  • 2
  • 18
  • 29
  • Well, I changed the code a bit List city = initialCityInput.get(index); to List city = (List)initialCityInput.get(index); which removed one of the two errors but I am still having the same problem with Integer min = Collections.min(city); – T44v1 Nov 12 '17 at 21:46
0

Well, I looked around a bit and I was basically overcomplicating the task through using multidimensional arraylists. I changed the code quite a bit:

public class GreedyTSP {

  public static int[] greedySolution(int[][] adjacencyMatrix) {
      List<Integer> visitedCities = new ArrayList<>();
        int min = Integer.MAX_VALUE;
        int startLocation = 0;
        int tempStartLocation = 0;
        int[] resultArray = new int[adjacencyMatrix.length+1];
        visitedCities.add(0);


        while(visitedCities.size() < adjacencyMatrix.length ){
            for(int i = 0; i < adjacencyMatrix.length; i++){
                if(!visitedCities.contains(i) && adjacencyMatrix[startLocation][i] < min){
                    min = adjacencyMatrix[startLocation][i];
                    tempStartLocation = i;
                }

            }
            startLocation = tempStartLocation;
            visitedCities.add(tempStartLocation);
            min = Integer.MAX_VALUE;
        }

        visitedCities.add(0);
        for(int i = 0; i < resultArray.length; i++){
            int temp = visitedCities.get(i);
            resultArray[i] = temp;
        }
        return resultArray;
    }
}

This will solve the task using a greedy algorithm

T44v1
  • 157
  • 1
  • 1
  • 9