fix: bad range management in bit.py
- use sensor_range * domain_width - add asserts - cleaner bit.neighborhood
This commit is contained in:
parent
b0feb71840
commit
ce190c5681
3 changed files with 32 additions and 17 deletions
31
sho/bit.py
31
sho/bit.py
|
|
@ -1,3 +1,4 @@
|
|||
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
|
||||
|
||||
|
|
|
|||
11
sho/num.py
11
sho/num.py
|
|
@ -1,3 +1,4 @@
|
|||
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
|
||||
|
||||
|
|
|
|||
7
snp.py
7
snp.py
|
|
@ -1,3 +1,4 @@
|
|||
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),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue