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 numpy as np
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
|
@ -9,9 +10,15 @@ from . import x,y,pb
|
||||||
|
|
||||||
def cover_sum(sol, domain_width, sensor_range):
|
def cover_sum(sol, domain_width, sensor_range):
|
||||||
"""Compute the coverage quality of the given array of bits."""
|
"""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))
|
domain = np.zeros((domain_width,domain_width))
|
||||||
sensors = to_sensors(sol)
|
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):
|
def to_sensors(sol):
|
||||||
|
|
@ -21,6 +28,7 @@ def to_sensors(sol):
|
||||||
>>> to_sensors([[1,0],[1,0]])
|
>>> to_sensors([[1,0],[1,0]])
|
||||||
[(0, 0), (0, 1)]
|
[(0, 0), (0, 1)]
|
||||||
"""
|
"""
|
||||||
|
assert(len(sol)>0)
|
||||||
sensors = []
|
sensors = []
|
||||||
for i in range(len(sol)):
|
for i in range(len(sol)):
|
||||||
for j in range(len(sol[i])):
|
for j in range(len(sol[i])):
|
||||||
|
|
@ -46,23 +54,22 @@ def rand(domain_width, nb_sensors):
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
def neighb_square(sol, scale, domain_width):
|
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
|
# Copy, because Python pass by reference
|
||||||
# and we may not want to alter the original solution.
|
# and we may not want to alter the original solution.
|
||||||
new = copy.copy(sol)
|
new = copy.copy(sol)
|
||||||
for py in range(len(sol)):
|
for py in range(len(sol)):
|
||||||
for px in range(len(sol[py])):
|
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:
|
if sol[py][px] == 1:
|
||||||
new[py][px] = 0 # Remove original position.
|
new[py][px] = 0 # Remove original position.
|
||||||
d = np.random.randint(-scale//2,scale//2,2)
|
# Add a one somewhere around.
|
||||||
if py+y(d) < 0 :
|
w = scale//2 * domain_width
|
||||||
d[1] = np.random.randint(-py,scale//2)
|
ny = np.random.randint(py-w,py+w)
|
||||||
if py+y(d) >= domain_width :
|
nx = np.random.randint(px-w,px+w)
|
||||||
d[1] = np.random.randint(-scale//2,domain_width-py)
|
ny = min(max(0,ny),domain_width-1)
|
||||||
if px+y(d) < 0 :
|
nx = min(max(0,nx),domain_width-1)
|
||||||
d[0] = np.random.randint(0,scale//2)
|
new[ny][nx] = 1
|
||||||
if px+x(d) >= domain_width :
|
|
||||||
d[0] = np.random.randint(-scale//2,domain_width-px)
|
|
||||||
new[py+y(d)][px+x(d)] = 1
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
|
|
||||||
11
sho/num.py
11
sho/num.py
|
|
@ -1,3 +1,4 @@
|
||||||
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from . import pb
|
from . import pb
|
||||||
|
|
@ -13,6 +14,7 @@ def to_sensors(sol):
|
||||||
>>> to_sensors([0,1,2,3])
|
>>> to_sensors([0,1,2,3])
|
||||||
[(0, 1), (2, 3)]
|
[(0, 1), (2, 3)]
|
||||||
"""
|
"""
|
||||||
|
assert(len(sol)>0)
|
||||||
sensors = []
|
sensors = []
|
||||||
for i in range(0,len(sol),2):
|
for i in range(0,len(sol),2):
|
||||||
sensors.append( ( int(round(sol[i])), int(round(sol[i+1])) ) )
|
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):
|
def cover_sum(sol, domain_width, sensor_range):
|
||||||
"""Compute the coverage quality of the given vector."""
|
"""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))
|
domain = np.zeros((domain_width,domain_width))
|
||||||
sensors = to_sensors(sol)
|
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):
|
def neighb_square(sol, scale, domain_width):
|
||||||
"""Draw a random vector in a square of witdh `scale`
|
"""Draw a random vector in a square of witdh `scale`
|
||||||
around the given one."""
|
around the given one."""
|
||||||
# TODO handle constraints
|
|
||||||
new = sol + (np.random.random(len(sol)) * scale - scale/2)
|
new = sol + (np.random.random(len(sol)) * scale - scale/2)
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
|
|
||||||
7
snp.py
7
snp.py
|
|
@ -1,3 +1,4 @@
|
||||||
|
import math
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
@ -19,7 +20,7 @@ if __name__=="__main__":
|
||||||
help="Number of sensors")
|
help="Number of sensors")
|
||||||
|
|
||||||
can.add_argument("-r", "--sensor-range", metavar="RATIO", default=0.3, type=float,
|
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,
|
can.add_argument("-w", "--domain-width", metavar="NB", default=30, type=int,
|
||||||
help="Domain width (a number of cells)")
|
help="Domain width (a number of cells)")
|
||||||
|
|
@ -48,7 +49,7 @@ if __name__=="__main__":
|
||||||
|
|
||||||
# Minimum checks.
|
# Minimum checks.
|
||||||
assert(0 < the.nb_sensors)
|
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.domain_width)
|
||||||
assert(0 < the.iters)
|
assert(0 < the.iters)
|
||||||
|
|
||||||
|
|
@ -89,7 +90,7 @@ if __name__=="__main__":
|
||||||
val,sol = algo.greedy(
|
val,sol = algo.greedy(
|
||||||
make.func(num.cover_sum,
|
make.func(num.cover_sum,
|
||||||
domain_width = the.domain_width,
|
domain_width = the.domain_width,
|
||||||
sensor_range = the.sensor_range * the.domain_width),
|
sensor_range = the.sensor_range),
|
||||||
make.init(num.rand,
|
make.init(num.rand,
|
||||||
dim = d * the.nb_sensors,
|
dim = d * the.nb_sensors,
|
||||||
scale = the.domain_width),
|
scale = the.domain_width),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue