Commit ce190c56 authored by nojhan's avatar nojhan
Browse files

fix: bad range management in bit.py

- use sensor_range * domain_width
- add asserts
- cleaner bit.neighborhood
parent b0feb718
import math
import numpy as np
import copy
......@@ -9,9 +10,15 @@ from . import x,y,pb
def cover_sum(sol, domain_width, sensor_range):
"""Compute the coverage quality of the given array of bits."""
assert(0 < sensor_range <= math.sqrt(2))
assert(0 < domain_width)
assert(len(sol)>0)
domain = np.zeros((domain_width,domain_width))
sensors = to_sensors(sol)
return np.sum(pb.coverage(domain, sensors, sensor_range))
cov = pb.coverage(domain, sensors, sensor_range*domain_width)
s = np.sum(cov)
assert(s >= len(sensors))
return s
def to_sensors(sol):
......@@ -21,6 +28,7 @@ def to_sensors(sol):
>>> to_sensors([[1,0],[1,0]])
[(0, 0), (0, 1)]
"""
assert(len(sol)>0)
sensors = []
for i in range(len(sol)):
for j in range(len(sol[i])):
......@@ -46,23 +54,22 @@ def rand(domain_width, nb_sensors):
########################################################################
def neighb_square(sol, scale, domain_width):
"""Draw a random array by moving ones to adjacent cells."""
"""Draw a random array by moving every ones to adjacent cells."""
# Copy, because Python pass by reference
# and we may not want to alter the original solution.
new = copy.copy(sol)
for py in range(len(sol)):
for px in range(len(sol[py])):
# Indices order is (y,x) in order to match
# coordinates of images (row,col).
if sol[py][px] == 1:
new[py][px] = 0 # Remove original position.
d = np.random.randint(-scale//2,scale//2,2)
if py+y(d) < 0 :
d[1] = np.random.randint(-py,scale//2)
if py+y(d) >= domain_width :
d[1] = np.random.randint(-scale//2,domain_width-py)
if px+y(d) < 0 :
d[0] = np.random.randint(0,scale//2)
if px+x(d) >= domain_width :
d[0] = np.random.randint(-scale//2,domain_width-px)
new[py+y(d)][px+x(d)] = 1
# Add a one somewhere around.
w = scale//2 * domain_width
ny = np.random.randint(py-w,py+w)
nx = np.random.randint(px-w,px+w)
ny = min(max(0,ny),domain_width-1)
nx = min(max(0,nx),domain_width-1)
new[ny][nx] = 1
return new
import math
import numpy as np
from . import pb
......@@ -13,6 +14,7 @@ def to_sensors(sol):
>>> to_sensors([0,1,2,3])
[(0, 1), (2, 3)]
"""
assert(len(sol)>0)
sensors = []
for i in range(0,len(sol),2):
sensors.append( ( int(round(sol[i])), int(round(sol[i+1])) ) )
......@@ -21,9 +23,15 @@ def to_sensors(sol):
def cover_sum(sol, domain_width, sensor_range):
"""Compute the coverage quality of the given vector."""
assert(0 < sensor_range <= math.sqrt(2))
assert(0 < domain_width)
assert(len(sol)>0)
domain = np.zeros((domain_width,domain_width))
sensors = to_sensors(sol)
return np.sum(pb.coverage(domain, sensors, sensor_range))
cov = pb.coverage(domain, sensors, sensor_range*domain_width)
s = np.sum(cov)
assert(s >= len(sensors))
return s
########################################################################
......@@ -42,7 +50,6 @@ def rand(dim, scale):
def neighb_square(sol, scale, domain_width):
"""Draw a random vector in a square of witdh `scale`
around the given one."""
# TODO handle constraints
new = sol + (np.random.random(len(sol)) * scale - scale/2)
return new
import math
import numpy as np
import matplotlib.pyplot as plt
......@@ -19,7 +20,7 @@ if __name__=="__main__":
help="Number of sensors")
can.add_argument("-r", "--sensor-range", metavar="RATIO", default=0.3, type=float,
help="Sensors' range (as a fraction of domain width)")
help="Sensors' range (as a fraction of domain width, max is √2)")
can.add_argument("-w", "--domain-width", metavar="NB", default=30, type=int,
help="Domain width (a number of cells)")
......@@ -48,7 +49,7 @@ if __name__=="__main__":
# Minimum checks.
assert(0 < the.nb_sensors)
assert(0 < the.sensor_range <= 1)
assert(0 < the.sensor_range <= math.sqrt(2))
assert(0 < the.domain_width)
assert(0 < the.iters)
......@@ -89,7 +90,7 @@ if __name__=="__main__":
val,sol = algo.greedy(
make.func(num.cover_sum,
domain_width = the.domain_width,
sensor_range = the.sensor_range * the.domain_width),
sensor_range = the.sensor_range),
make.init(num.rand,
dim = d * the.nb_sensors,
scale = the.domain_width),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment