- schiebe4 hinzugefĆ¼gt
[schiebespiel.git] / MinSchritte.java
blob380ca5ce42e974253e9069cca76ff3b22687bc42
1 import java.util.*;
2 import java.lang.*;
3 import java.math.BigInteger;
6 class MinSchritte {
7 class SteinCoords {
8 int x,y;
9 SteinCoords(int x, int y) {
10 this.x = x;
11 this.y = y;
13 public int distanz(SteinCoords sc) {
14 return Math.abs(x - sc.x) + Math.abs(y - sc.y);
18 /* Index 0 -> Leere
19 Index 1 -> Einer
20 Index 2 -> Zweier horizontal
21 Index 3 -> Zweier vertikal
22 Index 4 -> Vierer */
23 ArrayList< ArrayList<SteinCoords> > zielCoords = new ArrayList< ArrayList<SteinCoords> >();
25 ArrayList< ArrayList<SteinCoords> > findCoords(Knoten k) {
27 ArrayList<SteinCoords> einer = new ArrayList<SteinCoords>();
28 ArrayList<SteinCoords> zweier_horiz = new ArrayList<SteinCoords>();
29 ArrayList<SteinCoords> zweier_vertik = new ArrayList<SteinCoords>();
30 ArrayList<SteinCoords> vierer = new ArrayList<SteinCoords>();
31 SteinCoords sc;
33 int[][] feld = k.get_spielfeld();
34 for(int x = 0; x < feld.length; ++x) {
35 for(int y = 0; y < feld[0].length; ++y) {
36 switch(feld[x][y]) {
37 case Knoten.einer:
38 sc = new SteinCoords(x,y);
39 einer.add(sc);
40 break;
41 case Knoten.zweier_links:
42 sc = new SteinCoords(x,y);
43 zweier_horiz.add(sc);
44 break;
45 case Knoten.zweier_oben:
46 sc = new SteinCoords(x,y);
47 zweier_vertik.add(sc);
48 break;
49 case Knoten.vierer_ro:
50 sc = new SteinCoords(x,y);
51 vierer.add(sc);
52 break;
53 default:
54 break;
58 ArrayList<ArrayList<SteinCoords>> coords = new ArrayList<ArrayList<SteinCoords>>();
59 coords.add(einer);
60 coords.add(zweier_horiz);
61 coords.add(zweier_vertik);
62 coords.add(vierer);
64 return coords;
67 MinSchritte(Knoten ziel) {
68 setZielCoords(ziel);
71 void setZielCoords(Knoten ziel) {
72 zielCoords = findCoords(ziel);
75 int computeLuftlinie(Knoten k) {
77 PermutationGenerator x;
78 int[] indices;
79 int luftlinie = 0;
80 ArrayList<ArrayList<SteinCoords>> kCoords = findCoords(k);
81 ArrayList<SteinCoords> scList, zscList;
83 for (int i=0; i<4; ++i) {
84 int minSum = 0;
85 scList = kCoords.get(i);
86 zscList = zielCoords.get(i);
87 x = new PermutationGenerator(scList.size());
88 for (int j=0; j<scList.size(); ++j) {
89 minSum += scList.get(j).distanz(zscList.get(j));
91 while(x.hasMore()) {
92 int tmpSum = 0;
93 indices = x.getNext();
94 for (int j=0; j<scList.size(); ++j) {
95 tmpSum += scList.get(j).distanz(zscList.get(indices[j]));
97 // System.out.println(i + " " + tmpSum);
98 if (minSum > tmpSum) {
99 minSum = tmpSum;
102 luftlinie += minSum;
105 return luftlinie;
110 //--------------------------------------
111 // Systematically generate permutations.
112 //--------------------------------------
114 class PermutationGenerator {
116 private int[] a;
117 private BigInteger numLeft;
118 private BigInteger total;
120 //-----------------------------------------------------------
121 // Constructor. WARNING: Don't make n too large.
122 // Recall that the number of permutations is n!
123 // which can be very large, even when n is as small as 20 --
124 // 20! = 2,432,902,008,176,640,000 and
125 // 21! is too big to fit into a Java long, which is
126 // why we use BigInteger instead.
127 //----------------------------------------------------------
129 public PermutationGenerator (int n) {
130 if (n < 1) {
131 throw new IllegalArgumentException ("Min 1");
133 a = new int[n];
134 total = getFactorial (n);
135 reset ();
138 //------
139 // Reset
140 //------
142 public void reset () {
143 for (int i = 0; i < a.length; i++) {
144 a[i] = i;
146 numLeft = new BigInteger (total.toString ());
149 //------------------------------------------------
150 // Return number of permutations not yet generated
151 //------------------------------------------------
153 public BigInteger getNumLeft () {
154 return numLeft;
157 //------------------------------------
158 // Return total number of permutations
159 //------------------------------------
161 public BigInteger getTotal () {
162 return total;
165 //-----------------------------
166 // Are there more permutations?
167 //-----------------------------
169 public boolean hasMore() {
170 return numLeft.compareTo (BigInteger.ZERO) == 1;
173 //------------------
174 // Compute factorial
175 //------------------
177 private static BigInteger getFactorial (int n) {
178 BigInteger fact = BigInteger.ONE;
179 for (int i = n; i > 1; i--) {
180 fact = fact.multiply (new BigInteger (Integer.toString (i)));
182 return fact;
185 //--------------------------------------------------------
186 // Generate next permutation (algorithm from Rosen p. 284)
187 //--------------------------------------------------------
189 public int[] getNext () {
191 if (numLeft.equals (total)) {
192 numLeft = numLeft.subtract (BigInteger.ONE);
193 return a;
196 int temp;
198 // Find largest index j with a[j] < a[j+1]
200 int j = a.length - 2;
201 while (a[j] > a[j+1]) {
202 j--;
205 // Find index k such that a[k] is smallest integer
206 // greater than a[j] to the right of a[j]
208 int k = a.length - 1;
209 while (a[j] > a[k]) {
210 k--;
213 // Interchange a[j] and a[k]
215 temp = a[k];
216 a[k] = a[j];
217 a[j] = temp;
219 // Put tail end of permutation after jth position in increasing order
221 int r = a.length - 1;
222 int s = j + 1;
224 while (r > s) {
225 temp = a[s];
226 a[s] = a[r];
227 a[r] = temp;
228 r--;
229 s++;
232 numLeft = numLeft.subtract (BigInteger.ONE);
233 return a;