1
0

3 Revīzijas 5e362d1323 ... 0d298612b6

Autors SHA1 Ziņojums Datums
  Leon Palluch 0d298612b6 Merge branch 'algorithm' 4 gadi atpakaļ
  Leon Palluch b0686c9d6b finished christofides 4 gadi atpakaļ
  Leon Palluch 60eb49f02b Merge remote-tracking branch 'origin/master' into algorithm 4 gadi atpakaļ

+ 31 - 31
src/pathgame/algorithm/DijkstraMagic.java

@@ -7,7 +7,7 @@ import pathgame.tilemap.TileMap;
 import java.util.ArrayList;
 
 public class DijkstraMagic {
-    private int townID = -1;
+    private int townID = 18;
     private ArrayList<Coord> towns = new ArrayList<>();
     private TileMap map;
     private Node2D[][] weightMap;
@@ -16,16 +16,18 @@ public class DijkstraMagic {
     public DijkstraMagic(TileMap map) {
         this.map = map;
 
-        //weightMap = new Node2D[map.getWidth()][map.getHeight()];
-        weightMap = new Node2D[5][15];
+        weightMap = new Node2D[map.getWidth()][map.getHeight()];
+        //weightMap = new Node2D[5][15];
 
         setup();
 
+        printWeightMap();
+
         for(int i = 0; i < towns.size(); i++) {
             doMagicforTown(i);
         }
 
-        //printDijkstraResult();
+        printDijkstraResult();
     }
 
     public ArrayList<ArrayList<SaleRoute>> getSalesPitch() {
@@ -179,7 +181,7 @@ public class DijkstraMagic {
     private void setup() {
         //find towns
         //mock implementation
-
+        /*
         //test start
         towns.add(new Coord(0, 0));
         towns.add(new Coord(2, 3));
@@ -192,21 +194,22 @@ public class DijkstraMagic {
         //new test
         towns.add(new Coord(1, 3));
         towns.add(new Coord(1, 5));
-        towns.add(new Coord(2, 8));
-        towns.add(new Coord(0, 2));
-        towns.add(new Coord(0, 5));
-        towns.add(new Coord(0, 10));
-        towns.add(new Coord(0, 14));
-        towns.add(new Coord(1, 0));
-        towns.add(new Coord(1, 7));
-        towns.add(new Coord(1, 9));
-        towns.add(new Coord(1, 11));
+
         towns.add(new Coord(1, 14));
+        towns.add(new Coord(0, 10));
+        //towns.add(new Coord(2, 8));
+        //towns.add(new Coord(0, 2));
+        //towns.add(new Coord(0, 5));
+        //towns.add(new Coord(0, 14));
+        //towns.add(new Coord(1, 0));
+        //towns.add(new Coord(1, 7));
+        //towns.add(new Coord(1, 9));
+        //towns.add(new Coord(1, 11));*/
 
 
 
-        weightMap[0][0] = new Node2D(1);
-        weightMap[1][0] = new Node2D(5);
+        /*weightMap[0][0] = new Node2D(1);
+        weightMap[1][0] = new Node2D(1);
         weightMap[2][0] = new Node2D(1);
         weightMap[3][0] = new Node2D(5);
         weightMap[4][0] = new Node2D(5);
@@ -224,7 +227,7 @@ public class DijkstraMagic {
         weightMap[4][2] = new Node2D(1);
 
         weightMap[0][3] = new Node2D(1);
-        weightMap[1][3] = new Node2D(10);
+        weightMap[1][3] = new Node2D(1);
         weightMap[2][3] = new Node2D(1);
         weightMap[3][3] = new Node2D(1);
         weightMap[4][3] = new Node2D(5);
@@ -236,7 +239,7 @@ public class DijkstraMagic {
         weightMap[4][4] = new Node2D(5);
 
         weightMap[0][5] = new Node2D(1);
-        weightMap[1][5] = new Node2D(5);
+        weightMap[1][5] = new Node2D(1);
         weightMap[2][5] = new Node2D(1);
         weightMap[3][5] = new Node2D(5);
         weightMap[4][5] = new Node2D(5);
@@ -248,13 +251,13 @@ public class DijkstraMagic {
         weightMap[4][6] = new Node2D(1);
 
         weightMap[0][7] = new Node2D(1);
-        weightMap[1][7] = new Node2D(10);
+        weightMap[1][7] = new Node2D(1);
         weightMap[2][7] = new Node2D(1);
         weightMap[3][7] = new Node2D(1);
         weightMap[4][7] = new Node2D(1);
 
         weightMap[0][8] = new Node2D(1);
-        weightMap[1][8] = new Node2D(10);
+        weightMap[1][8] = new Node2D(1);
         weightMap[2][8] = new Node2D(1);
         weightMap[3][8] = new Node2D(1);
         weightMap[4][8] = new Node2D(5);
@@ -262,7 +265,7 @@ public class DijkstraMagic {
         weightMap[0][9] = new Node2D(1);
         weightMap[1][9] = new Node2D(1);
         weightMap[2][9] = new Node2D(1);
-        weightMap[3][9] = new Node2D(5);
+        weightMap[3][9] = new Node2D(1);
         weightMap[4][9] = new Node2D(5);
 
         weightMap[0][10] = new Node2D(1);
@@ -272,7 +275,7 @@ public class DijkstraMagic {
         weightMap[4][10] = new Node2D(5);
 
         weightMap[0][11] = new Node2D(1);
-        weightMap[1][11] = new Node2D(10);
+        weightMap[1][11] = new Node2D(1);
         weightMap[2][11] = new Node2D(1);
         weightMap[3][11] = new Node2D(5);
         weightMap[4][11] = new Node2D(1);
@@ -293,7 +296,7 @@ public class DijkstraMagic {
         weightMap[1][14] = new Node2D(1);
         weightMap[2][14] = new Node2D(1);
         weightMap[3][14] = new Node2D(5);
-        weightMap[4][14] = new Node2D(5);
+        weightMap[4][14] = new Node2D(5);*/
 
         //test end
 
@@ -322,26 +325,23 @@ public class DijkstraMagic {
         towns.add(new Coord(28, 10));*/
 
 
-        /*for(int x = 0; x < map.getWidth(); x++) {
+        for(int x = 0; x < map.getWidth(); x++) {
             for(int y = 0; y < map.getHeight(); y++) {
 
                 //actual implementation - find towns; townID needs to be set to correct value
 
-                /*if(map.getTile(x, y).getId() == townID) {
+                if(map.getTile(x, y).getId() == townID) {
                     towns.add(new Coord(x, y));
-                }*/
+                }
 
                 //translate map to weightMap
                 //TODO: boats
 
-                /*PlayerAbilities test = new PlayerAbilities(0, 0, 0, 0, 0, 0, 0);
+                PlayerAbilities test = new PlayerAbilities("", 0, 0, 0, 0, 0, 0, 0);
 
                 weightMap[x][y] = new Node2D(map.getTile(x, y).getEnergyCost(test));
-
             }
-        }*/
-
-        //printWeightMap();
+        }
     }
 
     private void printDijkstraMap() {

+ 5 - 1
src/pathgame/algorithm/OddDegreeList.java

@@ -25,12 +25,16 @@ public class OddDegreeList {
         return items.get(getOffsetPos(offSet));
     }
 
-    public int makeUsed(int offSet) {
+    public int makeOffsetUsed(int offSet) {
         int pos = getOffsetPos(offSet);
         itemUsed.set(pos, true);
         return pos;
     }
 
+    public void makePosUsed(int pos) {
+        itemUsed.set(pos, true);
+    }
+
     public void makeUnused(int pos) {
         itemUsed.set(pos, false);
     }

+ 28 - 4
src/pathgame/algorithm/Permutation.java

@@ -5,12 +5,16 @@ public class Permutation {
     private int[] vals;
     private int[] minVals;
     private int minCost = Integer.MAX_VALUE;
+    private int thingsPerPos;
+    private boolean overFlow = false;
     //public int tempCounter1 = 0;
     //public int tempCounter2 = 0;
 
-    public Permutation(int listSize) {
-        this.size = (listSize/2) - 1;
+    public Permutation(int listSize, int thingsPerPos) {
+        this.thingsPerPos = thingsPerPos;
+        this.size = (listSize/thingsPerPos) - 1;
         vals = new int[size];
+
     }
 
     public int getValAtPos (int pos) {
@@ -24,8 +28,8 @@ public class Permutation {
         return false;
     }
 
-    private int getMaxOfPos (int pos) {
-        return 2 * (size - pos);
+    public int getMaxOfPos (int pos) {
+        return thingsPerPos * (size - pos);
     }
 
     public int size() {
@@ -39,6 +43,22 @@ public class Permutation {
         }
     }
 
+    public void increaseLowest() {
+        boolean over = true;
+
+        for(int i = size-1; i >= 0; i--) {
+            if(getValAtPos(i) < getMaxOfPos(i)) {
+                increaseAtPos(i);
+                over = false;
+                break;
+            }
+        }
+
+        if(over) {
+            overFlow = true;
+        }
+    }
+
     public int getMinCost() {
         return minCost;
     }
@@ -59,6 +79,10 @@ public class Permutation {
         System.out.println();
     }
 
+    public boolean isOverFlowing() {
+        return overFlow;
+    }
+
     public void printMinPermut() {
         for(int i = 0; i < size; i++) {
             System.out.print(minVals[i] + " ");

+ 154 - 12
src/pathgame/algorithm/TravellingSalesAlg.java

@@ -11,6 +11,7 @@ public class TravellingSalesAlg {
 
         ArrayList<ArrayList<SaleRoute>> salesPitch = dijkstra.getSalesPitch();
 
+
         //make minimum spanning tree
         ArrayList<TreeEdge> MSTree = makeMSTree(salesPitch);
 
@@ -18,20 +19,161 @@ public class TravellingSalesAlg {
         ArrayList<TreeEdge> oddDegEdges = makeOddDegEdges(MSTree, salesPitch);
         MSTree.addAll(oddDegEdges);
 
+        //finde euler tour
         ArrayList<Integer> eulerTour = getEulerTour(MSTree);
 
-        return 10;
+        //cut short
+        cutShort(eulerTour);
+
+        //TODO: write to logging file
+
+        //calculate the total weight of the tour using the edge table (salesPitch)
+        int tourWeight = calcTourWeight(eulerTour, salesPitch);
+        System.out.println("min cost: " + tourWeight);
+        return tourWeight;
+
+        //brute force
+        //return bruteForce(salesPitch);
+    }
+
+    private static int bruteForce(ArrayList<ArrayList<SaleRoute>> salesPitch) {
+        Permutation permutation = new Permutation(salesPitch.size(), 1);
+        OddDegreeList nodeList = new OddDegreeList();
+        for(int i = 0; i < salesPitch.size()+1; i++) {
+            nodeList.add(i);
+        }
+
+        while(!permutation.isOverFlowing()) {
+            int newSum = bruteSumPermut(permutation, salesPitch, nodeList);
+            if(newSum < permutation.getMinCost()) {
+                permutation.setMinCost(newSum);
+            }
+            /*permutation.printPermut();
+            System.out.println(newSum);
+            System.out.println();*/
+            permutation.increaseLowest();
+        }
+        permutation.makePermutMinimal();
+        permutation.printPermut();
+        System.out.println("min cost: " + permutation.getMinCost());
+
+
+        return 0;
+    }
+
+    private static int bruteSumPermut(Permutation permutation, ArrayList<ArrayList<SaleRoute>> salesPitch, OddDegreeList nodeList) {
+        int sum = 0;
+        nodeList.resetUsed();
+
+        int first = -1;
+        int last = -1;
+
+        for(int i = 0; i < permutation.size(); i++) {
+            int pos = nodeList.getUnused(permutation.getValAtPos(i));
+            //System.out.println("pos: " + pos);
+
+            if(first == -1) {
+                first = pos;
+            }
+            else {
+                //System.out.println(last + " - " + pos);
+                sum += bruteWeight(last, pos, salesPitch);
+                //System.out.println(sum);
+            }
+            last = pos;
+
+            nodeList.makePosUsed(pos);
+        }
+        //System.out.println(last + " - " + nodeList.getUnused(0));
+        int pos = nodeList.getUnused(0);
+        sum += bruteWeight(last, pos, salesPitch);
+
+        //System.out.println(pos + " - " + first);
+        sum += bruteWeight(pos, first, salesPitch);
+
+        return sum;
+    }
+
+    private static int bruteWeight(int first, int sec, ArrayList<ArrayList<SaleRoute>> salesPitch) {
+        if(first < sec) {
+            return salesPitch.get(first).get(sec-first-1).getTotalCost();
+        }
+        else {
+            return salesPitch.get(sec).get(first-sec-1).getTotalCost();
+        }
+    }
+
+    private static int calcTourWeight(ArrayList<Integer> tour, ArrayList<ArrayList<SaleRoute>> salesPitch) {
+        int totalWeight = 0;
+
+        for(int i = 0; i < tour.size()-1; i++) {
+            int startNode, endNode;
+
+            if(tour.get(i) < tour.get(i+1)) {
+                startNode = tour.get(i);
+                endNode = tour.get(i+1) - startNode - 1;
+            }
+            else {
+                startNode = tour.get(i+1);
+                endNode = tour.get(i) - startNode - 1;
+
+            }
+
+            //System.out.println(startNode + "/" + endNode + ": " + salesPitch.get(startNode).get(endNode).getTotalCost());
+
+            totalWeight += salesPitch.get(startNode).get(endNode).getTotalCost();
+        }
+
+        //System.out.println(totalWeight);
+
+        return totalWeight;
+    }
+
+    private static void cutShort(ArrayList<Integer> eulerTour) {
+        int counter = 2;
+
+        while(counter < eulerTour.size()-1) {
+            int current = eulerTour.get(counter);
+
+            boolean found = false;
+
+            for(int i = 0; i < counter; i++) {
+                if(eulerTour.get(i) == current) {
+                    found = true;
+                    break;
+                }
+            }
+
+            if(found) {
+                eulerTour.remove(counter);
+            }
+            else {
+                counter++;
+            }
+
+        }
+
+        /*System.out.println("cut tour");
+
+        for(int i = 0; i < eulerTour.size(); i++) {
+            if(i != 0) {
+                System.out.print(" - ");
+            }
+            System.out.print(eulerTour.get(i));
+        }
+        System.out.println();*/
+
     }
 
     private static ArrayList<Integer> getEulerTour(ArrayList<TreeEdge> graph) {
         ArrayList<Integer> tour = new ArrayList<>();
 
         while (graph.size() > 0) {
-            System.out.println();
+            /*System.out.println();
             for(int i = 0; i < graph.size(); i++) {
                 System.out.println("'" + graph.get(i).getSrc() + " : " + graph.get(i).getDest());
             }
-            System.out.println();
+            System.out.println();*/
 
             if(tour.size() == 0) {
                 tour = getSubtour(graph, graph.get(0).getSrc());
@@ -60,7 +202,7 @@ public class TravellingSalesAlg {
 
                 mergeTours(tour, subTour);
 
-                System.out.println("merged tour");
+                /*System.out.println("merged tour");
 
                 for(int i = 0; i < tour.size(); i++) {
                     if(i != 0) {
@@ -68,7 +210,7 @@ public class TravellingSalesAlg {
                     }
                     System.out.print(tour.get(i));
                 }
-                System.out.println();
+                System.out.println();*/
             }
         }
 
@@ -91,13 +233,13 @@ public class TravellingSalesAlg {
             tour.add(next);
         }
 
-        for(int i = 0; i < tour.size(); i++) {
+        /*for(int i = 0; i < tour.size(); i++) {
             if(i != 0) {
                 System.out.print(" - ");
             }
             System.out.print(tour.get(i));
         }
-        System.out.println();
+        System.out.println();*/
 
         return tour;
     }
@@ -145,7 +287,7 @@ public class TravellingSalesAlg {
             }
         }
 
-        Permutation permut = new Permutation(oddDegs.size());
+        Permutation permut = new Permutation(oddDegs.size(), 2);
 
         calcPairShortest(oddDegs, salesPitch, permut, 0, 0);
         permut.makePermutMinimal();
@@ -170,9 +312,9 @@ public class TravellingSalesAlg {
 
     private static void addOddEdge(ArrayList<TreeEdge> oddEdges, OddDegreeList oddDegs, ArrayList<ArrayList<SaleRoute>> salesPitch, int offSet) {
         int orig = oddDegs.getUnused(0);
-        oddDegs.makeUsed(0);
+        oddDegs.makeOffsetUsed(0);
         int dest = oddDegs.getUnused(offSet);
-        oddDegs.makeUsed(offSet);
+        oddDegs.makeOffsetUsed(offSet);
 
         oddEdges.add(new TreeEdge(orig, dest, salesPitch.get(orig).get(dest - orig - 1).getTotalCost()));
     }
@@ -210,8 +352,8 @@ public class TravellingSalesAlg {
                     System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");*/
                 }
                 else {
-                    int used1 = oddDegs.makeUsed(0);
-                    int used2 = oddDegs.makeUsed(offSet);
+                    int used1 = oddDegs.makeOffsetUsed(0);
+                    int used2 = oddDegs.makeOffsetUsed(offSet);
                     calcPairShortest(oddDegs, salesPitch, permut, permutPos+1, costSoFar+edgeWeight);
                     oddDegs.makeUnused(used1);
                     oddDegs.makeUnused(used2);