Initial Commit
clcolmerau

clcolmerau commited on 2023-12-29 10:36:15
Showing 5 changed files, with 678 additions and 0 deletions.

... ...
@@ -0,0 +1,92 @@
1
+package Projet;
2
+import java.util.*;
3
+import java.lang.Math;
4
+
5
+
6
+public class Heuristique1 extends ProblemZ2
7
+{
8
+	private LinkedList<Vector2> states;
9
+	private LinkedList<Vector2> exploredStates;
10
+	private LinkedList<Vector2> toExploreState;
11
+	private LinkedList<Vector2> nextIteration;
12
+	private LinkedList<Vector2> actions;
13
+	private LinkedList<Vector2> path;
14
+	private Vector2 startingState;
15
+	private Vector2 finalState;
16
+
17
+	//Constructor
18
+	public Heuristique1(Vector2 startingState, Vector2 finalState, LinkedList<Vector2> actions)
19
+	{
20
+		this.states = new LinkedList<Vector2>();
21
+		this.exploredStates = new LinkedList<Vector2>();
22
+		this.toExploreState = new LinkedList<Vector2>();
23
+		this.nextIteration = new LinkedList<Vector2>();
24
+		this.actions = new LinkedList<Vector2>();
25
+		this.path = new LinkedList<Vector2>();
26
+		this.startingState = startingState;
27
+		this.finalState = finalState;
28
+		this.states.add(startingState);
29
+		this.toExploreState.add(startingState);
30
+		this.actions = actions;
31
+	}
32
+
33
+	public LinkedList<Vector2> solveBFS(int maxIteration)
34
+	{
35
+
36
+		float computeLimit = 0;
37
+		for(int j = 0 ; j < this.actions.size() ; j++)
38
+			computeLimit += this.actions.get(j).magnitude();
39
+		computeLimit += this.startingState.distance(this.finalState);
40
+
41
+		int limit = (int) (Math.ceil(computeLimit));
42
+				System.out.println(limit);
43
+		for(int i = 1 ; i<= maxIteration ; i++)
44
+		{
45
+			while(this.toExploreState.size() != 0)
46
+			{
47
+				Vector2 e = this.toExploreState.get(0);
48
+
49
+				//Check if final state
50
+				if(e.equals(this.finalState))
51
+				{
52
+					while(e.parent() != null)
53
+					{
54
+						this.path.add(0,e);
55
+						e = e.parent();
56
+					}
57
+					this.path.add(0,this.startingState);
58
+					this.states.add(e);
59
+					return this.path;
60
+				}
61
+			
62
+				//Creates successors
63
+				for(int j = 0 ; j < this.actions.size() ; j++)
64
+				{
65
+					Vector2 s = suc(e,this.actions.get(j));
66
+					this.states.add(s);
67
+					//System.out.println(this.toExploreState.contains(s));	
68
+					if((!contains(this.exploredStates,s) && !contains(this.toExploreState,s)))
69
+					{
70
+						//If in circle, treat now, else at next dichotomy
71
+						if(s.distance(this.finalState) <= limit)
72
+						{
73
+							this.toExploreState.add(s);
74
+						}
75
+						else
76
+						{
77
+							this.nextIteration.add(s);
78
+						}
79
+					}
80
+				}
81
+				this.exploredStates.add(e);
82
+				this.toExploreState.remove(0);
83
+			}
84
+			//Dichotomy
85
+			limit *= 2;
86
+			this.toExploreState.addAll(this.nextIteration);
87
+		}
88
+		return null;
89
+	}
90
+
91
+
92
+}
0 93
\ No newline at end of file
... ...
@@ -0,0 +1,386 @@
1
+package Projet;
2
+import java.util.*;
3
+import java.lang.Math;
4
+
5
+
6
+public class Heuristique2 extends ProblemZ2
7
+{
8
+	private LinkedList<Vector2> states;
9
+	private LinkedList<Vector2> exploredStates;
10
+	private LinkedList<Vector2> toExploreState;
11
+	private LinkedList<Vector2> nextIteration;
12
+	private LinkedList<Vector2> actions;
13
+	private LinkedList<LinkedList<Combination>> comb;
14
+	private LinkedList<Vector2> path;
15
+	private Vector2 startingState;
16
+	private Vector2 finalState;
17
+	private LinkedList<Jump> jumps;
18
+
19
+	//Constructor
20
+	public Heuristique2(Vector2 startingState, Vector2 finalState, LinkedList<Vector2> actions)
21
+	{
22
+		this.states = new LinkedList<Vector2>();
23
+		this.exploredStates = new LinkedList<Vector2>();
24
+		this.toExploreState = new LinkedList<Vector2>();
25
+		this.nextIteration = new LinkedList<Vector2>();
26
+		this.actions = new LinkedList<Vector2>();
27
+		this.comb = new LinkedList<LinkedList<Combination>>();
28
+		this.path = new LinkedList<Vector2>();
29
+		this.startingState = startingState;
30
+		this.finalState = finalState;
31
+		this.states.add(startingState);
32
+		this.toExploreState.add(startingState);
33
+		this.actions = actions;
34
+		this.jumps = new LinkedList<Jump>();
35
+	}
36
+
37
+	public LinkedList<Vector2> solveBFS(int maxIteration)
38
+	{
39
+
40
+		float computeLimit = 0;
41
+		for(int j = 0 ; j < this.actions.size() ; j++)
42
+			computeLimit += this.actions.get(j).magnitude();
43
+
44
+		int limit = (int) (Math.ceil(computeLimit));
45
+
46
+		computeCombination();
47
+		createJump(limit);
48
+
49
+		boolean firstIter = true;
50
+		for(int i = 1 ; i<= maxIteration ; i++)
51
+		{
52
+			while(this.toExploreState.size() != 0)
53
+			{
54
+				Vector2 e = this.toExploreState.get(0);
55
+
56
+				//Check if final state
57
+				if(e.equals(this.finalState))
58
+				{
59
+					LinkedList<Vector2> endPath = new LinkedList<Vector2>();
60
+					while(e.parent() != this.startingState)
61
+					{
62
+						endPath.add(0,e);
63
+						e = e.parent();
64
+					}
65
+					for(int j = 0 ; j < this.jumps.size() ; j++)
66
+					{
67
+						if(this.jumps.get(j).end().equals(e))
68
+						{
69
+							this.path.addAll(this.jumps.get(j).computePath());
70
+							break;
71
+						}
72
+					}
73
+					this.path.addAll(endPath);
74
+					return this.path;
75
+				}
76
+			
77
+				//On firest iteration, make jump instead of generic search
78
+				if(firstIter)
79
+				{
80
+					//Create successor using jumps
81
+					for(int j = 0 ; j < this.jumps.size() ; j++)
82
+					{
83
+						Vector2 s = this.jumps.get(j).end();
84
+						this.states.add(s);
85
+
86
+						if((!contains(this.exploredStates,s) && !contains(this.toExploreState,s)))
87
+						{
88
+							if(s.distance(this.finalState) <= limit)
89
+							{
90
+								this.toExploreState.add(s);
91
+							}
92
+							else
93
+							{
94
+								this.nextIteration.add(s);
95
+							}
96
+						}
97
+					}
98
+					firstIter = false;
99
+				}
100
+				else
101
+				{
102
+					//Create successor
103
+					for(int j = 0 ; j < this.actions.size() ; j++)
104
+					{
105
+						Vector2 s = suc(e,this.actions.get(j));
106
+						this.states.add(s);
107
+						if((!contains(this.exploredStates,s) && !contains(this.toExploreState,s)))
108
+						{
109
+							if(s.distance(this.finalState) <= limit)
110
+							{
111
+								this.toExploreState.add(s);
112
+							}
113
+							else
114
+							{
115
+								this.nextIteration.add(s);
116
+							}
117
+						}
118
+					}					
119
+				}
120
+				this.exploredStates.add(e);
121
+				this.toExploreState.remove(0);
122
+			}
123
+			//Dichotomy
124
+			limit *= 2;
125
+			this.toExploreState.addAll(this.nextIteration);
126
+			firstIter = true;
127
+		}
128
+		return null;
129
+	}
130
+
131
+	//Create linear combination using actions
132
+	private void computeCombination()
133
+	{
134
+		LinkedList<Vector2> temp;
135
+		LinkedList<Combination> newSize = new LinkedList<Combination>();
136
+
137
+		//Create size 1 commbination
138
+		for(int i = 0 ; i < this.actions.size() ; i++)
139
+		{
140
+			temp = new LinkedList<Vector2>();
141
+			temp.add(this.actions.get(i));
142
+			newSize.add(new Combination(temp));
143
+		}
144
+		this.comb.add(newSize);
145
+
146
+		//Create size n combination
147
+		for(int i = 1 ; i < this.actions.size() ; i++)
148
+		{
149
+			this.comb.add(new LinkedList<Combination>());
150
+			for(int j = 0 ; j < this.comb.size()/2 ; j++)
151
+			{
152
+				for(int n = 0 ; n < this.comb.get(j).size() ; n++)
153
+				{
154
+
155
+					for(int m = 0 ; m < this.comb.get(this.comb.size()-j-2).size(); m++)
156
+					{
157
+						temp = new LinkedList<Vector2>();
158
+						temp.addAll(this.comb.get(j).get(n).element());
159
+						temp.addAll(this.comb.get(this.comb.size()-j-2).get(m).element());
160
+						this.comb.get(i).add(new Combination(temp));
161
+					}
162
+				}
163
+			}
164
+			
165
+
166
+		}
167
+	}
168
+
169
+	//Create possible jumps
170
+	private void createJump(int limit)
171
+	{
172
+		for(int i = 0 ; i < this.comb.size() ; i++)
173
+		{
174
+			for(int j = 0 ; j < this.comb.get(i).size() ; j++)
175
+			{
176
+				LinkedList<Integer> alpha = new LinkedList<Integer>();
177
+				alpha = jump(limit, this.comb.get(i).get(j).value());
178
+				if(alpha != null)
179
+				{					
180
+					for(int k = 0 ; k < alpha.size() ; k++)
181
+					{
182
+						this.jumps.add(new Jump(this.startingState, alpha.get(k), this.comb.get(i).get(j)));
183
+					}
184
+				}
185
+			} 
186
+		}
187
+	}
188
+
189
+	//Compute the possible alpha to jump
190
+	private LinkedList<Integer> jump(int limit,Vector2 a)
191
+	{
192
+		double m;
193
+		double p;
194
+		double coefa;
195
+		double coefb;
196
+		double coefc;
197
+		if(a.y() == 0)
198
+		{
199
+			m = 0;
200
+			p = this.startingState.y();
201
+			coefa = m*m +1;
202
+			coefb = (-2*this.finalState.x()) + (2*m*p - 2) * (this.finalState.y() * m);
203
+			coefc = (this.finalState.x() * this.finalState.x()) + (p * p) - (2* this.finalState.y() * p) + (this.finalState.y() * this.finalState.y()) - (limit * limit);
204
+		}
205
+		else if(a.x() == 0)
206
+		{
207
+			m = 0;
208
+			p = this.startingState.x();
209
+			coefa = 1;
210
+			coefb = (-2*this.finalState.y());
211
+			coefc = (p * p) - (2* this.finalState.x() * p) + (this.finalState.y() * this.finalState.y()) - (limit * limit) + (this.finalState.x() * this.finalState.x());
212
+		}
213
+		else
214
+		{
215
+			m = a.x()/a.y();
216
+			p = this.startingState.y()/a.y();			
217
+			coefa = m*m +1;
218
+			coefb = (-2*this.finalState.x()) + (2*m*p - 2) * (this.finalState.y() * m);
219
+			coefc = (this.finalState.x() * this.finalState.x()) + (p * p) - (2* this.finalState.y() * p) + (this.finalState.y() * this.finalState.y()) - (limit * limit);
220
+		}
221
+		LinkedList<Integer> alpha = new LinkedList<Integer>();
222
+
223
+		double delta = Math.pow(coefb,2) - 4 * coefa * coefc;
224
+
225
+		//Can't reach the circle
226
+		if(delta < 0)
227
+		{
228
+			return alpha;
229
+		}
230
+		//Have 1 intersection with cirlce
231
+		if(delta == 0)
232
+		{
233
+			double x = - (coefb + Math.sqrt(delta))/(2*coefa);
234
+			double y = m*x + p;
235
+			if(x % 1 == 0 && y % 1 == 0)
236
+			{
237
+				double alpha1 = new Vector2((int)Math.floor(x),(int)Math.floor(y)).distance(this.startingState) / a.magnitude();
238
+				if(alpha1 % 1 ==0)
239
+					alpha.add((int)Math.floor(alpha1));
240
+			}
241
+			return alpha;
242
+		}
243
+		//Have 2 intersection
244
+		else 
245
+		{
246
+			if(a.x() != 0)
247
+			{
248
+				double x2 = (-coefb + Math.sqrt(delta))/(2*coefa);
249
+				double x1 = (-coefb - Math.sqrt(delta))/(2*coefa);
250
+				double y1 = m * x1 + p;
251
+				double y2 = m * x2 + p;
252
+				LinkedList<Vector2> validPoints = new LinkedList<Vector2>();
253
+				for(int i = (int)Math.ceil(x1) ; i <= (int)Math.floor(x2) ; i++)
254
+				{
255
+					if(m * i + p >= y1 && m * i + p <= y2)
256
+						validPoints.add(new Vector2(i,(int)Math.floor(m*i+p)));
257
+				}
258
+				for(int i = 0 ; i < validPoints.size() ; i++)
259
+				{
260
+					double alpha1 = validPoints.get(i).distance(this.startingState) / a.magnitude();
261
+					if(alpha1 % 1 == 0 && alpha1 > 0)
262
+						alpha.add((int)alpha1);
263
+				}				
264
+			}
265
+			//Particular case for x = k line 
266
+			else 
267
+			{
268
+				double y1 = (-coefb - Math.sqrt(delta))/(2*coefa);
269
+				double y2 = (-coefb + Math.sqrt(delta))/(2*coefa);
270
+				LinkedList<Vector2> validPoints = new LinkedList<Vector2>();
271
+				for(int i = (int)Math.ceil(y1) ; i <= (int)Math.floor(y2) ; i++)
272
+				{
273
+					validPoints.add(new Vector2((int)Math.floor(p),i));
274
+				}
275
+				for(int i = 0 ; i < validPoints.size() ; i++)
276
+				{
277
+					double alpha1 = validPoints.get(i).distance(this.startingState) / a.magnitude();
278
+					if(alpha1 % 1 == 0)
279
+						alpha.add((int)alpha1);
280
+				}				
281
+			}
282
+			return alpha;
283
+		}
284
+	}
285
+
286
+	//Definiton of combination
287
+	private class Combination
288
+	{
289
+		int size;
290
+		LinkedList<Vector2> element;
291
+
292
+		//Constructor
293
+		private Combination(LinkedList<Vector2> element)
294
+		{
295
+			this.element = new LinkedList<Vector2>();
296
+			this.element.addAll(element);
297
+			this.size = this.element.size();
298
+		}
299
+
300
+		//Getter
301
+		private int size()
302
+		{
303
+			return this.size;
304
+		}
305
+
306
+		private LinkedList<Vector2> element()
307
+		{
308
+			LinkedList<Vector2> temp = new LinkedList<Vector2>();
309
+			temp.addAll(element);
310
+			return temp;
311
+		}
312
+
313
+		//Value of the vector created by the combination
314
+		private Vector2 value()
315
+		{
316
+			int x = 0;
317
+			int y = 0;
318
+			for(int i = 0 ; i < this.size ; i++)
319
+			{
320
+				x += this.element.get(i).x();
321
+				y += this.element.get(i).y();
322
+			}
323
+			return new Vector2(x,y);
324
+		}
325
+
326
+		@Override
327
+		public String toString()
328
+		{
329
+			String r = "";
330
+			for(int i = 0 ; i < this.size ; i++)
331
+			{
332
+				r+= this.element.get(i).toString();
333
+			}
334
+			return r;
335
+		}
336
+	}
337
+
338
+	//Definition of jump
339
+	private class Jump
340
+	{
341
+		Vector2 start;
342
+		int alpha;
343
+		Combination comb;
344
+
345
+		//Constructor
346
+		private Jump(Vector2 start, int alpha, Combination comb)
347
+		{
348
+			this.comb = comb;
349
+			this.alpha = alpha;
350
+			this.start = start;
351
+		}
352
+
353
+		//Give the end point 
354
+		private Vector2 end()
355
+		{
356
+			int x = this.comb.value().x() * this.alpha;
357
+			int y = this.comb.value().y() * this.alpha;
358
+			
359
+			return new Vector2(x,y,start);
360
+		}
361
+
362
+		//Compute the path for printing
363
+		private LinkedList<Vector2> computePath()
364
+		{
365
+			LinkedList<Vector2> path = new LinkedList<Vector2>();
366
+			path.add(this.start);
367
+			for(int j = 0 ; j < this.comb.size() ; j++)
368
+			{
369
+				for(int i = 0 ; i < this.alpha ; i++)
370
+				{
371
+					path.add(suc(path.get(i + j * this.alpha),this.comb.element().get(j)));
372
+				}
373
+			}
374
+			return path;
375
+		}
376
+
377
+		@Override
378
+		public String toString()
379
+		{
380
+			String r = "";
381
+			r += this.alpha * this.comb.value().x() + "," + this.alpha * this.comb.value().y();
382
+			return r;
383
+		}
384
+	}
385
+
386
+}
0 387
\ No newline at end of file
... ...
@@ -0,0 +1,60 @@
1
+import Projet.*;
2
+import java.util.*;
3
+import java.lang.Math;
4
+import java.lang.System;
5
+
6
+public class Main
7
+{
8
+	public static void main(String[] args) {
9
+		long start = System.nanoTime();
10
+		LinkedList<Vector2> actions = new LinkedList<Vector2>();
11
+		//Unit test
12
+		/*actions.add(new Vector2(0,1)); 
13
+		actions.add(new Vector2(0,-1)); 
14
+		actions.add(new Vector2(1,0)); 
15
+		actions.add(new Vector2(-1,0)); 
16
+		Heuristique1 p = new Heuristique1(new Vector2(1,0), new Vector2(0,257), actions);
17
+		printResult(p.solveBFS(1));*/
18
+
19
+
20
+		//Second data set
21
+		/*actions.add(new Vector2(-1,1)); 
22
+		actions.add(new Vector2(-1,2)); 
23
+		actions.add(new Vector2(1,-1)); 
24
+		actions.add(new Vector2(2,-1)); 
25
+		Heuristique1 p = new Heuristique1(new Vector2(1,0), new Vector2(0,257), actions);*/
26
+
27
+		//Unit test
28
+		/*actions.add(new Vector2(1,0));
29
+		actions.add(new Vector2(0,1));
30
+		Heuristique2 p = new Heuristique2(new Vector2(0,0), new Vector2(10,10), actions);*/
31
+
32
+		//Second data set
33
+		/*actions.add(new Vector2(-1,1));
34
+		actions.add(new Vector2(-1,2));
35
+		actions.add(new Vector2(1,-1));
36
+		actions.add(new Vector2(2,-1));
37
+		Heuristique2 p = new Heuristique2(new Vector2(1,0), new Vector2(0,1025), actions);*/
38
+
39
+		long finish = System.nanoTime();
40
+		System.out.println("Execution time : " + (finish - start)/1000 + "ms");
41
+		//printResult(p.solveBFS(1));
42
+
43
+	}
44
+
45
+	//Print the path found
46
+	private static void printResult(LinkedList<Vector2> result)
47
+	{
48
+		if(result == null)
49
+			System.out.println("No solution found");
50
+		else
51
+		{
52
+			System.out.println("Path found :");
53
+
54
+			for(int i = 0 ; i < result.size() ; i++)
55
+			{
56
+				System.out.println(result.get(i).toString());
57
+			}
58
+		}
59
+	}
60
+}
0 61
\ No newline at end of file
... ...
@@ -0,0 +1,46 @@
1
+package Projet;
2
+import java.util.*;
3
+import java.lang.Math;
4
+
5
+
6
+public class ProblemZ2
7
+{
8
+	private LinkedList<Vector2> states;
9
+	private LinkedList<Vector2> exploredStates;
10
+	private LinkedList<Vector2> toExploreState;
11
+	private LinkedList<Vector2> nextIteration;
12
+	private LinkedList<Vector2> actions;
13
+	private LinkedList<Vector2> path;
14
+	private Vector2 startingState;
15
+	private Vector2 finalState;
16
+
17
+
18
+	//Recoded because the original did reference comparaison instead of value
19
+	protected boolean contains(LinkedList<Vector2> l, Vector2 v)
20
+	{
21
+		for(int i = 0 ; i < l.size() ; i++)
22
+		{
23
+			if(v.equals(l.get(i)))
24
+				return true;
25
+		}
26
+		return false;
27
+	}
28
+
29
+
30
+	protected boolean contains(LinkedList<Integer> l, Integer v)
31
+	{
32
+		for(int i = 0 ; i < l.size() ; i++)
33
+		{
34
+			if(v.equals(l.get(i)))
35
+				return true;
36
+		}
37
+		return false;
38
+	}
39
+
40
+	//Create a successor
41
+	protected Vector2 suc(Vector2 s, Vector2 a)
42
+	{
43
+		return new Vector2(s.x() + a.x(), s.y() + a.y(), s);
44
+	}
45
+
46
+}
0 47
\ No newline at end of file
... ...
@@ -0,0 +1,94 @@
1
+package Projet;
2
+import java.util.*;
3
+import java.lang.Math;
4
+
5
+public class Vector2 implements Comparable<Vector2>
6
+{
7
+	private int x;
8
+	private int y;
9
+	//Used for point/state
10
+	private Vector2 parent;
11
+
12
+	//Constructors
13
+	public Vector2(int x, int y)
14
+	{
15
+		this.x = x;
16
+		this.y = y;
17
+		this.parent = null;
18
+	}
19
+
20
+	public Vector2(int x, int y, Vector2 parent)
21
+	{
22
+		this.x = x;
23
+		this.y = y;
24
+		this.parent = parent;
25
+	}
26
+
27
+	public Vector2(Vector2 v, Vector2 u)
28
+	{
29
+		this.x = v.x()+u.x();
30
+		this.y = v.y()+u.y();
31
+		this.parent = null;
32
+	}
33
+
34
+	//Getter
35
+	public int x()
36
+	{
37
+		return this.x;
38
+	}
39
+
40
+	public int y()
41
+	{
42
+		return this.y;
43
+	}
44
+
45
+	public Vector2 parent()
46
+	{
47
+		return this.parent;
48
+	}
49
+
50
+	//Setter
51
+	public void parent(Vector2 parent)
52
+	{
53
+		this.parent = parent;
54
+	}
55
+
56
+	//Compute magnitude
57
+	public double magnitude()
58
+	{
59
+		return Math.sqrt(x*x + y*y);
60
+	}
61
+
62
+	//Check if vectors are colinear (not used)
63
+	public boolean colinear(Vector2 other)
64
+	{
65
+		int crossProduct;
66
+		crossProduct = this.x() * other.x() + this.y() * other.y();
67
+		return crossProduct == 0 ? true : false;
68
+	}
69
+
70
+	//Compute the ditance between two point
71
+	public double distance(Vector2 other)
72
+	{
73
+		return Math.sqrt(Math.pow(this.x- other.x(),2) + Math.pow(this.y - other.y(),2));
74
+	}
75
+
76
+	//Value comparison of two vector
77
+	public int compareTo(Vector2 other)
78
+	{
79
+		if(this.x == other.x() && this.y == other.y())
80
+			return 1;
81
+		return this.magnitude() < other.magnitude() ? -1 : 1;
82
+	}
83
+
84
+	public boolean equals(Vector2 other)
85
+	{
86
+		return (this.x == other.x() && this.y == other.y());
87
+	}
88
+
89
+	@Override
90
+	public String toString()
91
+	{
92
+		return "("+String.valueOf(this.x) + "," + String.valueOf(this.y)+")";
93
+	}
94
+}
0 95
\ No newline at end of file
1 96