This repository was archived by the owner on Feb 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSimulatedAnnealing.java
More file actions
151 lines (124 loc) · 5 KB
/
SimulatedAnnealing.java
File metadata and controls
151 lines (124 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package SimulatedAnnealing;
import Principal.Doctor;
import Principal.Main;
import Principal.Solution;
import static Principal.Main.*;
import java.util.ArrayList;
/**
*
* @author kzr
*/
public class SimulatedAnnealing {
public boolean memetic = false;
Solution memSol = null;
public void run(Solution s) {
memetic = true;
memSol = s;
run();
}
public void run() {
// Set initial temp
double temp = Main.TEMPERATURE;
// Cooling rate
double coolingRate = 0.03;
Solution currentSolution = new Solution();
currentSolution.generateIndividual();
if (memetic) {
coolingRate = 0.10;
currentSolution = memSol;
} else {
//System.out.println("SimulatedAnnealing:\nInitial solution distance: " + currentSolution.getCost());
}
// Set as current best
Solution best = new Solution(currentSolution.getSol(), currentSolution.getDoctorsAsignated(), currentSolution.getCost());
// Loop until system has cooled
while (temp > 1) {
// Create new neighbour tour
//Solution newSolution = new Solution(currentSolution.getSol());
Solution newSolution = new Solution(currentSolution.getSol(), currentSolution.getDoctorsAsignated(), currentSolution.getCost());
// Generamos un doctor aleatorio que no tenga el maximo de pacientes
newSolution = neighbour(newSolution);
// boolean exito = false;
// int numDoc = 0;
// while (!exito) {
//
// numDoc = (int) (doctors.size() * Math.random());
// Doctor d = doctors.get(numDoc);
// if (newSolution.puedeAsignar(d)) {
// exito = true;
// }
// }
// int numPac = (int) (patients.size() * Math.random());
// newSolution.doctorsAsignated[newSolution.sol[numPac]]--;
// //CAMBIAMOS EL DOCTOR ASIGNADO AL PACIENTE POR EL GENERADO ALEATORIO
// newSolution.cambiarDoctor(numDoc, numPac);
newSolution.calculateCost();
// Get energy of solutions
double currentEnergy = currentSolution.getCost();
double neighbourEnergy = newSolution.getCost();
// Decide if we should accept the neighbour
if (acceptanceProbability(currentEnergy, neighbourEnergy, temp) >= Math.random()) {
//System.out.println("Aceptada");
currentSolution = new Solution(newSolution.getSol(), newSolution.getDoctorsAsignated(), newSolution.getCost());
}
// Keep track of the best solution found
if (currentSolution.getCost() < best.getCost()) {
best = new Solution(currentSolution.getSol(), currentSolution.getDoctorsAsignated(), currentSolution.getCost());
}
// Cool system when the solution is better
temp *= 1 - coolingRate;
}
if (!memetic&& !Main.DEBUG) {
System.out.println("Simulated Annealing:\n" + "Final solution distance: " + best.getCost()
+ "\nCoste medicos: " + best.getDinero() + " €\tDistancia "
+ "total: " + best.getDistancia() + " km");
}
if(Main.DEBUG){
System.out.println(best.getCost());
}
}
public Solution neighbour(Solution sol) {
ArrayList<Integer> bagDoc = new ArrayList();
ArrayList<Integer> bagPat = new ArrayList();
for (int i = 0; i < Main.doctors.size(); i++) {
bagDoc.add(i);
}
for (int j = 0; j < Main.patients.size(); j++) {
bagPat.add(j);
}
int num1 = -1;
int num2 = -1;
boolean exito = false;
while (!exito) {
int num1Aux = (int) Math.random() * bagPat.size();
num1 = bagPat.get(num1Aux);
bagPat.remove(num1Aux);
//ANTES SE LE ASIGNABA UN PACIENTE
while (!exito) {
int num2aux = (int) Math.random() * bagDoc.size();
num2 = bagDoc.get(num2aux);
bagDoc.remove(num2aux);
Doctor d = Main.doctors.get(num2);
if (sol.puedeAsignar(d)) {
exito = true;
} else {
System.out.println("Error mutate");
Main.error++;
}
}
}
sol.doctorsAsignated[sol.sol[num1]]--;
sol.cambiarDoctor(num2, num1);
sol.calculateCost();
return sol;
}
public static double acceptanceProbability(double energy, double newEnergy, double temperature) {
// If the new solution is better, accept it
if (newEnergy < energy) {
return 1.0;
}
// If the new solution is worse, calculate an acceptance probability
//System.out.println(Math.exp(((energy - newEnergy) ) / temperature));
return Math.exp((energy - newEnergy) / temperature);
}
}