-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathes_uni-objective.py
executable file
·179 lines (160 loc) · 5.36 KB
/
es_uni-objective.py
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#! /usr/bin/python
# -*- coding: utf-8 -*-
import math
import random
# Number of districts
districts_number = 16
maximun_bomber_stations = 5
maximun_bomber_in_district = 1
# Districts neighbors
neighbors = {}
neighbors[1] = [1, 2 , 4 , 5]
neighbors[2] = [2, 1 , 3 , 5 , 6]
neighbors[3] = [3 , 2 , 6 , 7]
neighbors[4] = [4 , 1 , 5 , 8 , 10 , 11]
neighbors[5] = [5 , 1 , 2 , 4 , 6 , 8]
neighbors[6] = [6 , 2 , 3 , 5 , 7 , 8 , 9]
neighbors[7] = [7 , 3 , 6 , 9 , 13]
neighbors[8] = [8 , 4 , 5 , 6 , 9 , 11 , 12]
neighbors[9] = [9 , 6 , 7 , 8 , 12 , 13]
neighbors[10] = [10 , 4 , 11 , 14]
neighbors[11] = [11 , 4 , 8 , 10 , 12 , 14 , 15]
neighbors[12] = [12 , 8 , 9 , 11 , 13 , 14 , 15]
neighbors[13] = [13 , 7 , 9 , 12 , 15 , 16]
neighbors[14] = [14 , 10 , 11 , 12 , 15]
neighbors[15] = [15 , 11 , 12 , 13 , 14 , 16]
neighbors[16] = [16 , 13 , 15]
def districtsCoverBySomeSolution(stations):
"""
Calculate the number of districts cover by one solution
Given a bomber station (for each one), return all adjacent neighbors.
"""
districts_cover = dict()
cent = False
cont = 0
while cont < len(stations):
# Itself is cover
if stations[cont] > 0:
districts_cover[cont+1] = True
# Get all neighbors from station-district location
#print cont+1,' ',neighbors[cont+1]
for distrito in neighbors[cont+1]:
districts_cover[distrito] = True
# Exit loop if all districts all cover
if len(districts_cover) == districts_number:
cent = True
cont += 1
return districts_cover
def f1(solution):
"""
WE SHOULD TO MAXIMIZE
This function calculate the districts cover by one vector of solution.
This vector is the index where bombers has a station.
"""
return float(len(districtsCoverBySomeSolution(solution)))
def f2(solution):
"""
WE SHOULD TO MINIMIZE
Calculate the number of overlaps.
"""
acum = 0
n = len(solution)
i = 0
# For each bomber station in the solution, calculate the overlaps
# with the next other bomber stations in solutions vector
while i < n - 1:
if solution[i] > 0:
# Next solutions given i
j = i + 1
while j < n:
if solution[j] > 0:
# Sumarize overlaps between neighbors
if len(set(neighbors[i + 1]) & set(neighbors[j + 1])) > 1:
acum += len(set(neighbors[i + 1]) & set(neighbors[j + 1]))
j += 1
i += 1
return acum
def f(solution):
"""
This function is the global aproach to solve the main problem, try
to maximize the sum of (maximize #1 function + maximize - #2 function)
"""
return -0.8*f1(solution) + 0.2*f2(solution)
def generateRandSolution(x = None):
"""
Generate a vector with random values
If x is None, this function create one new random vector,
if it is not, copy x vector and permut two position in order
to get a new individual of x entorn.
"""
solution = []
if x == None:
for i in range(1 , districts_number+1):
solution.append(random.randrange(0 , maximun_bomber_in_district))
else:
for i in x:
solution.append(i)
n = len(solution)
# Apply two random transformations in two positions in order to
# get a "near" new solution
for i in range(0 , 2):
rand_index = random.randrange(1 , n)
# 0.5 of propability in each branch
if random.random() < 0.5:
solution[rand_index] += 1
else:
solution[rand_index] -= 1
# Check if values are in range [0 .. N]
if solution[rand_index] < 0:
solution[rand_index] = 0
elif solution[rand_index] > maximun_bomber_in_district:
solution[rand_index] = maximun_bomber_in_district
return solution
# General algorithm parameters
params = {}
# Initial temperature
params['temperature'] = 100.0
# Cooling factor
params['alpha'] = 0.9
# Steps number keeping the temperature
params['np'] = 20
# Final temperature
params['final_temperature'] = 0.01
# Number of iterations without improving
params['number_iterations_without_improves'] = 2000
# Total number of iterations
params['nnum'] = 0
PE = []
# Generate random initial solution
x = generateRandSolution()
#x = [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
PE.append(x)
n = 0
# Start the algorithm
cont = 0
while (params['temperature'] > params['final_temperature'] and
params['nnum'] < params['number_iterations_without_improves']):
# Get solution of x entorn
y = generateRandSolution(x)
# Calculate distance between two solutions
delta = f(y) - f(x)
# If delta is better, accept new solution
if delta < 0.0:
x = []
x.extend(y)
# If it is not better, compute probabilities to accept other solutions
else:
if (random.random() < math.exp(- float(delta) / params['temperature'])):
x = []
x.extend(y)
# Low temperature
if params['nnum'] % params['np'] == 0:
params['temperature'] *= params['alpha']
params['nnum'] += 1
print f(x)
print '-----------------'
print x
print 'f1: %f' % f1(x)
print 'f2: %f' % f2(x)
print 'f: %f' % f(x)
print len(districtsCoverBySomeSolution(x))