Cleanup.
This commit is contained in:
parent
8a507c08fa
commit
26dfb6d305
|
@ -1,21 +1,7 @@
|
||||||
# Use atan2 instead of acos to calc angle; atan2(x,y) of the point we potentially want to add
|
# Use atan2 instead of acos to calc angle; atan2(x,y) of the point we potentially want to add
|
||||||
import random
|
|
||||||
from collections import namedtuple
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from math import acos, sqrt
|
from math import acos, sqrt
|
||||||
|
|
||||||
Point = namedtuple('Point', 'x y')
|
from util import Vector, Point, gen_point, display
|
||||||
Vector = namedtuple('Vector', 'x y')
|
|
||||||
|
|
||||||
|
|
||||||
def gen_point():
|
|
||||||
a = random.uniform(1, 5)
|
|
||||||
b = random.uniform(1, 5)
|
|
||||||
|
|
||||||
x_i = random.uniform(1, 5)
|
|
||||||
p_i = Point(x_i, a * x_i + b)
|
|
||||||
|
|
||||||
return p_i
|
|
||||||
|
|
||||||
|
|
||||||
def calc_angle(v1: Vector, v2: Vector) -> float:
|
def calc_angle(v1: Vector, v2: Vector) -> float:
|
||||||
|
@ -31,25 +17,10 @@ def calc_angle(v1: Vector, v2: Vector) -> float:
|
||||||
return acos(hmmmmmmm)
|
return acos(hmmmmmmm)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def calc_vector(p1: Point, p2: Point) -> Vector:
|
def calc_vector(p1: Point, p2: Point) -> Vector:
|
||||||
return Vector((p2.x - p1.x), (p2.y - p1.y))
|
return Vector((p2.x - p1.x), (p2.y - p1.y))
|
||||||
|
|
||||||
|
|
||||||
def display(points, hull):
|
|
||||||
x = [point.x for point in points]
|
|
||||||
y = [point.y for point in points]
|
|
||||||
|
|
||||||
h_x = [point.x for point in hull]
|
|
||||||
h_y = [point.y for point in hull]
|
|
||||||
|
|
||||||
plt.plot(h_x, h_y, 'ro-')
|
|
||||||
|
|
||||||
plt.scatter(x, y)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
|
|
||||||
def rapper(points: set):
|
def rapper(points: set):
|
||||||
min_pt = min(points)
|
min_pt = min(points)
|
||||||
hull = [min_pt]
|
hull = [min_pt]
|
||||||
|
|
|
@ -1,97 +1,63 @@
|
||||||
import random
|
from util import gen_point, Side, Point, display
|
||||||
from collections import namedtuple
|
|
||||||
from enum import Enum, auto
|
|
||||||
import matplotlib.pyplot as plt
|
def sidedness(p1, p2, p3, eps=0.0000001):
|
||||||
|
|
||||||
Point = namedtuple('Point', ['x', 'y'])
|
# Find line from p1 to p2, ask where p3 is in relation to this
|
||||||
|
|
||||||
|
y = p3.y * (p2.x - p1.x)
|
||||||
class Side(Enum):
|
x = p3.x
|
||||||
ON = auto()
|
|
||||||
ABOVE = auto()
|
a = (p2.y - p1.y)
|
||||||
BELOW = auto()
|
b = p2.y * (p2.x - p1.x) - a * p2.x
|
||||||
|
|
||||||
|
if y - eps < a * x + b < y + eps:
|
||||||
def sidedness(p1, p2, p3, eps=0.0000001):
|
return Side.ON
|
||||||
|
elif y > a * x + b:
|
||||||
# Find line from p1 to p2, ask where p3 is in relation to this
|
return Side.ABOVE
|
||||||
|
return Side.BELOW
|
||||||
y = p3.y * (p2.x - p1.x)
|
|
||||||
x = p3.x
|
|
||||||
|
# test
|
||||||
a = (p2.y - p1.y)
|
|
||||||
b = p2.y * (p2.x - p1.x) - a * p2.x
|
|
||||||
|
p1 = Point(4, 4)
|
||||||
if y - eps < a * x + b < y + eps:
|
p2 = Point(0, 0)
|
||||||
return Side.ON
|
p3 = Point(5, 2)
|
||||||
elif y > a * x + b:
|
|
||||||
return Side.ABOVE
|
|
||||||
return Side.BELOW
|
# print(sidedness(p1, p2, p3))
|
||||||
|
|
||||||
|
|
||||||
# test
|
def graham_scan(points):
|
||||||
|
|
||||||
|
# A funky issue where both a and b become negative in the sidedness test causes us to have to use
|
||||||
p1 = Point(4, 4)
|
# Side.ABOVE for both tests, regardless of UH or LH.
|
||||||
p2 = Point(0, 0)
|
|
||||||
p3 = Point(5, 2)
|
sorted_points = sorted(points)
|
||||||
|
|
||||||
|
UH = sorted_points[:2]
|
||||||
# print(sidedness(p1, p2, p3))
|
#del sorted_points[0]
|
||||||
|
|
||||||
|
for s in sorted_points[2:]:
|
||||||
def genPoint():
|
while len(UH) > 1 and (sidedness(UH[-2], UH[-1], s) != Side.ABOVE):
|
||||||
a = random.uniform(1, 5)
|
del UH[-1]
|
||||||
b = random.uniform(1, 5)
|
UH.append(s)
|
||||||
|
|
||||||
x_i = random.uniform(1, 5)
|
reversed_list = list(reversed(sorted_points))
|
||||||
p_i = Point(x_i, a * x_i + b)
|
reversed_list.append(UH[0])
|
||||||
|
LH = reversed_list[:2]
|
||||||
return p_i
|
#del reversed_list[0]
|
||||||
|
|
||||||
|
for s in reversed_list[2:]:
|
||||||
def graham_scan(points):
|
while len(LH) > 1 and (sidedness(LH[-2], LH[-1], s) != Side.ABOVE):
|
||||||
|
del LH[-1]
|
||||||
# A funky issue where both a and b become negative in the sidedness test causes us to have to use
|
LH.append(s)
|
||||||
# Side.ABOVE for both tests, regardless of UH or LH.
|
|
||||||
|
return UH, LH
|
||||||
sorted_points = sorted(points)
|
|
||||||
|
|
||||||
UH = sorted_points[:2]
|
p = [gen_point() for _ in range(30)]
|
||||||
#del sorted_points[0]
|
UH, LH = graham_scan(p)
|
||||||
|
|
||||||
for s in sorted_points[2:]:
|
display(p, {*UH, *LH})
|
||||||
while len(UH) > 1 and (sidedness(UH[-2], UH[-1], s) != Side.ABOVE):
|
|
||||||
del UH[-1]
|
|
||||||
UH.append(s)
|
|
||||||
|
|
||||||
reversed_list = list(reversed(sorted_points))
|
|
||||||
reversed_list.append(UH[0])
|
|
||||||
LH = reversed_list[:2]
|
|
||||||
#del reversed_list[0]
|
|
||||||
|
|
||||||
for s in reversed_list[2:]:
|
|
||||||
while len(LH) > 1 and (sidedness(LH[-2], LH[-1], s) != Side.ABOVE):
|
|
||||||
del LH[-1]
|
|
||||||
LH.append(s)
|
|
||||||
|
|
||||||
return UH, LH
|
|
||||||
|
|
||||||
|
|
||||||
p = [genPoint() for _ in range(30)]
|
|
||||||
UH, LH = graham_scan(p)
|
|
||||||
|
|
||||||
x = [point.x for point in p]
|
|
||||||
y = [point.y for point in p]
|
|
||||||
|
|
||||||
UH_x = [point.x for point in UH]
|
|
||||||
UH_y = [point.y for point in UH]
|
|
||||||
|
|
||||||
LH_x = [point.x for point in LH]
|
|
||||||
LH_y = [point.y for point in LH]
|
|
||||||
|
|
||||||
plt.plot(UH_x, UH_y, 'ro-')
|
|
||||||
plt.plot(LH_x, LH_y, 'ro-')
|
|
||||||
|
|
||||||
plt.scatter(x,y)
|
|
||||||
plt.show()
|
|
172
h2/mbc.py
172
h2/mbc.py
|
@ -1,67 +1,12 @@
|
||||||
import random
|
|
||||||
import statistics
|
import statistics
|
||||||
from collections import namedtuple
|
|
||||||
from enum import Enum, auto
|
|
||||||
from math import inf
|
from math import inf
|
||||||
from typing import Set, List, Tuple
|
from typing import Set, List, Tuple
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
from util import Side, Point, gen_point, display
|
||||||
import numpy as np
|
|
||||||
from scipy.optimize import linprog
|
|
||||||
|
|
||||||
Point = namedtuple('Point', 'x y')
|
|
||||||
|
|
||||||
|
|
||||||
def gen_point(lower: int, upper: int) -> Point:
|
def sidedness(slope: float, intersection: float, p3: Point, linprog_flipper: callable, eps=0.0000001) -> Side:
|
||||||
a = random.uniform(lower, upper)
|
# finds where a point is in regards to a line
|
||||||
b = random.uniform(lower, upper)
|
|
||||||
|
|
||||||
x_i = random.uniform(lower, upper)
|
|
||||||
p_i = Point(x_i, a * x_i + b)
|
|
||||||
p_i = Point(a, b)
|
|
||||||
return p_i
|
|
||||||
|
|
||||||
|
|
||||||
def display(points: Set[Point], hull: Set[Point]):
|
|
||||||
x = [point.x for point in points]
|
|
||||||
y = [point.y for point in points]
|
|
||||||
|
|
||||||
h_x = [point.x for point in hull]
|
|
||||||
h_y = [point.y for point in hull]
|
|
||||||
|
|
||||||
plt.plot(h_x, h_y, 'ro')
|
|
||||||
|
|
||||||
plt.scatter(x, y)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
|
|
||||||
def display_line_only(points: Set[Point], slope: int, intercept: int, line_points: Set[Point]):
|
|
||||||
x = [point.x for point in points]
|
|
||||||
y = [point.y for point in points]
|
|
||||||
|
|
||||||
plt.scatter(x, y)
|
|
||||||
|
|
||||||
# Plot a line from slope and intercept
|
|
||||||
axes = plt.gca()
|
|
||||||
x_vals = np.array(axes.get_xlim())
|
|
||||||
y_vals = intercept + slope * x_vals
|
|
||||||
|
|
||||||
for point in line_points:
|
|
||||||
plt.plot(point.x, point.y, 'go')
|
|
||||||
|
|
||||||
plt.plot(x_vals, y_vals, '--')
|
|
||||||
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
|
|
||||||
class Side(Enum):
|
|
||||||
ON = auto()
|
|
||||||
ABOVE = auto()
|
|
||||||
BELOW = auto()
|
|
||||||
|
|
||||||
|
|
||||||
def sidedness(slope: int, intersection: int, p3: Point, linprog_flipper: callable, eps=0.0000001) -> Side:
|
|
||||||
# finds where a point is in regards to a line
|
|
||||||
if linprog_flipper(p3.y) - eps <= linprog_flipper(slope * p3.x + intersection) <= linprog_flipper(p3.y) + eps:
|
if linprog_flipper(p3.y) - eps <= linprog_flipper(slope * p3.x + intersection) <= linprog_flipper(p3.y) + eps:
|
||||||
return Side.ON
|
return Side.ON
|
||||||
elif p3.y > slope * p3.x + intersection:
|
elif p3.y > slope * p3.x + intersection:
|
||||||
|
@ -75,38 +20,19 @@ def solve_1dlp(c: float, constraints: List[Tuple[float, float]]):
|
||||||
:param constraints: [(ai, bi), ...]
|
:param constraints: [(ai, bi), ...]
|
||||||
:return: x1
|
:return: x1
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
min_ = -10000
|
if c > 0:
|
||||||
max_ = 10000
|
return max(b/a for a, b in constraints if a < 0)
|
||||||
|
return min(b/a for a, b in constraints if a > 0)
|
||||||
for constraint in constraints:
|
except ValueError: # unbounded
|
||||||
(a, b) = constraint
|
return -inf if c > 0 else inf
|
||||||
|
|
||||||
if a == 0:
|
|
||||||
assert(b >= 0)
|
|
||||||
|
|
||||||
if a > 0:
|
|
||||||
max_ = min(b/a, max_)
|
|
||||||
else:
|
|
||||||
min_ = max(b/a, min_)
|
|
||||||
|
|
||||||
|
|
||||||
if c > 0:
|
assert solve_1dlp(1, [(-1, -2)]) == 2
|
||||||
return min_
|
assert solve_1dlp(1, [(-1, -2), (-1, -3)]) == 3
|
||||||
else:
|
assert solve_1dlp(1, [(-1, -3), (-1, -2)]) == 3
|
||||||
return max_
|
assert solve_1dlp(-1, [(1, 3), (1, 2)]) == 2
|
||||||
|
assert solve_1dlp(1, [(-1, 3), (-1, 2)]) == -2
|
||||||
|
|
||||||
# if c > 0:
|
|
||||||
# return max(b/a for a, b in constraints if a < 0)
|
|
||||||
# return min(b/a for a, b in constraints if a > 0)
|
|
||||||
|
|
||||||
|
|
||||||
#assert solve_1dlp(1, [(-1, -2)]) == 2
|
|
||||||
#assert solve_1dlp(1, [(-1, -2), (-1, -3)]) == 3
|
|
||||||
#assert solve_1dlp(1, [(-1, -3), (-1, -2)]) == 3
|
|
||||||
#assert solve_1dlp(-1, [(1, 3), (1, 2)]) == 2
|
|
||||||
#assert solve_1dlp(1, [(-1, 3), (-1, 2)]) == -2
|
|
||||||
|
|
||||||
|
|
||||||
def solve_2dlp(c: Tuple[float, float], constraints: List[Tuple[Tuple[float, float], float]]):
|
def solve_2dlp(c: Tuple[float, float], constraints: List[Tuple[Tuple[float, float], float]]):
|
||||||
|
@ -115,69 +41,20 @@ def solve_2dlp(c: Tuple[float, float], constraints: List[Tuple[Tuple[float, floa
|
||||||
:param constraints: [(ai1, ai2, bi), ...]
|
:param constraints: [(ai1, ai2, bi), ...]
|
||||||
:return: x1, x2
|
:return: x1, x2
|
||||||
"""
|
"""
|
||||||
|
c1, c2 = c
|
||||||
|
x1, x2 = (-inf, -inf) if c1 > 0 else (inf, inf)
|
||||||
|
#random.shuffle(constraints)
|
||||||
|
|
||||||
if c[0] > 0:
|
for i, ((a1, a2), b) in enumerate(constraints[1:], start=1):
|
||||||
x1 = -10000
|
if a1*x1 + a2*x2 <= b:
|
||||||
else:
|
|
||||||
x1 = 10000
|
|
||||||
|
|
||||||
if c[1] > 0:
|
|
||||||
x2 = -10000
|
|
||||||
else:
|
|
||||||
x2 = 10000
|
|
||||||
|
|
||||||
our_constraints = []
|
|
||||||
for (a1, a2), b in constraints: # TODO: random.shuffle()
|
|
||||||
|
|
||||||
print("x1 and x2", x1, x2)
|
|
||||||
|
|
||||||
if len(our_constraints) == 0:
|
|
||||||
our_constraints.append(((a1, a2), b))
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print("{} + {} <= {}".format(a1*x1, a2*x2, b))
|
x1 = solve_1dlp(c1 - c2*a1/a2, [(ai1 - ai2*a1 / a2, bi - ai2*b / a2) for (ai1, ai2), bi in constraints[:i]])
|
||||||
if not (a1*x1 + a2*x2 <= b):
|
x2 = (b - a1*x1) / a2
|
||||||
|
|
||||||
constraint_for_1d = []
|
|
||||||
|
|
||||||
new_obj = c[0] - ((c[1]*a1)/a2)
|
|
||||||
|
|
||||||
for constraint in our_constraints:
|
|
||||||
(a_i1, a_i2), b_i = constraint
|
|
||||||
|
|
||||||
a_prime = a_i1 - ((a_i2*a1)/a2)
|
|
||||||
b_prime = b_i - ((a_i2*b)/a2)
|
|
||||||
constraint_for_1d.append((a_prime, b_prime))
|
|
||||||
|
|
||||||
print("obj", new_obj)
|
|
||||||
print("const", constraint_for_1d)
|
|
||||||
|
|
||||||
print("lol",[cons[0] for cons in constraint_for_1d])
|
|
||||||
# res = linprog([new_obj], [[cons[0]] for cons in constraint_for_1d], [[cons[1]] for cons in constraint_for_1d], bounds=[(None, None)])
|
|
||||||
x1 = solve_1dlp(new_obj, constraint_for_1d)
|
|
||||||
# x1 = res.x[0]
|
|
||||||
x2 = ((b/a2) - (a1/a2)*x1)
|
|
||||||
|
|
||||||
our_constraints.append(((a1, a2), b))
|
|
||||||
|
|
||||||
return x1, x2
|
return x1, x2
|
||||||
|
|
||||||
|
|
||||||
# assert solve_2dlp((-3, -2), [((-1, 3), 12), ((1, 1), 8), ((2, -1), 10)]) == (6, 2)
|
|
||||||
|
|
||||||
c = (-3, -2)
|
|
||||||
constraints = [
|
|
||||||
((-1, 3), 12),
|
|
||||||
((1, 1), 8),
|
|
||||||
((2, -1), 10),
|
|
||||||
]
|
|
||||||
# = (6.0, 2.0)
|
|
||||||
|
|
||||||
result = solve_2dlp(c, constraints)
|
|
||||||
print(result)
|
|
||||||
#exit()
|
|
||||||
|
|
||||||
|
|
||||||
def mbc_ch(points: Set[Point], linprog_flipper: callable) -> Set[Point]:
|
def mbc_ch(points: Set[Point], linprog_flipper: callable) -> Set[Point]:
|
||||||
if len(points) <= 2:
|
if len(points) <= 2:
|
||||||
return points
|
return points
|
||||||
|
@ -190,8 +67,8 @@ def mbc_ch(points: Set[Point], linprog_flipper: callable) -> Set[Point]:
|
||||||
pr = {p for p in points if p.x >= med_x}
|
pr = {p for p in points if p.x >= med_x}
|
||||||
|
|
||||||
# Find the bridge over the vertical line in pm
|
# Find the bridge over the vertical line in pm
|
||||||
c = [linprog_flipper(med_x), linprog_flipper(1)]
|
c = (linprog_flipper(med_x), linprog_flipper(1))
|
||||||
A = [[linprog_flipper(-p.x), linprog_flipper(-1)] for p in points]
|
A = [(linprog_flipper(-p.x), linprog_flipper(-1)) for p in points]
|
||||||
b = [linprog_flipper(-p.y) for p in points]
|
b = [linprog_flipper(-p.y) for p in points]
|
||||||
|
|
||||||
#result = linprog(c, A, b, bounds=[(None, None), (None, None)], options={"tol": 0.00001})
|
#result = linprog(c, A, b, bounds=[(None, None), (None, None)], options={"tol": 0.00001})
|
||||||
|
@ -205,9 +82,6 @@ def mbc_ch(points: Set[Point], linprog_flipper: callable) -> Set[Point]:
|
||||||
left_point = next(p for p in pl if sidedness(slope, intercept, p, linprog_flipper) == Side.ON)
|
left_point = next(p for p in pl if sidedness(slope, intercept, p, linprog_flipper) == Side.ON)
|
||||||
right_point = next(p for p in pr if sidedness(slope, intercept, p, linprog_flipper) == Side.ON)
|
right_point = next(p for p in pr if sidedness(slope, intercept, p, linprog_flipper) == Side.ON)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Prune the points between the two line points
|
# Prune the points between the two line points
|
||||||
pl = {p for p in pl if p.x <= left_point.x}
|
pl = {p for p in pl if p.x <= left_point.x}
|
||||||
pr = {p for p in pr if p.x >= right_point.x}
|
pr = {p for p in pr if p.x >= right_point.x}
|
||||||
|
|
|
@ -1,41 +1,7 @@
|
||||||
import random
|
|
||||||
from collections import namedtuple
|
|
||||||
from enum import Enum, auto
|
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
from util import Point, gen_point, display
|
||||||
|
|
||||||
Point = namedtuple('Point', 'x y')
|
|
||||||
|
|
||||||
|
|
||||||
class Side(Enum):
|
|
||||||
ON = auto()
|
|
||||||
ABOVE = auto()
|
|
||||||
BELOW = auto()
|
|
||||||
|
|
||||||
|
|
||||||
def display(points, hull):
|
|
||||||
x = [point.x for point in points]
|
|
||||||
y = [point.y for point in points]
|
|
||||||
|
|
||||||
h_x = [point.x for point in hull]
|
|
||||||
h_y = [point.y for point in hull]
|
|
||||||
|
|
||||||
plt.plot(h_x, h_y, 'ro')
|
|
||||||
|
|
||||||
plt.scatter(x, y)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
|
|
||||||
def gen_point():
|
|
||||||
a = random.uniform(1, 5)
|
|
||||||
b = random.uniform(1, 5)
|
|
||||||
|
|
||||||
x_i = random.uniform(1, 5)
|
|
||||||
p_i = Point(x_i, a * x_i + b)
|
|
||||||
|
|
||||||
return p_i
|
|
||||||
|
|
||||||
|
|
||||||
def distance(a, b, c):
|
def distance(a, b, c):
|
||||||
|
|
58
h2/util.py
Normal file
58
h2/util.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import random
|
||||||
|
from collections import namedtuple
|
||||||
|
from enum import Enum, auto
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
Point = namedtuple('Point', 'x y')
|
||||||
|
Vector = namedtuple('Vector', 'x y')
|
||||||
|
|
||||||
|
|
||||||
|
def gen_point(lower: int = 0, upper: int = 10) -> Point:
|
||||||
|
a = random.uniform(lower, upper)
|
||||||
|
b = random.uniform(lower, upper)
|
||||||
|
|
||||||
|
x_i = random.uniform(lower, upper)
|
||||||
|
p_i = Point(x_i, a * x_i + b)
|
||||||
|
p_i = Point(a, b)
|
||||||
|
return p_i
|
||||||
|
|
||||||
|
|
||||||
|
def display(points: Set[Point], hull: Set[Point]):
|
||||||
|
x = [point.x for point in points]
|
||||||
|
y = [point.y for point in points]
|
||||||
|
|
||||||
|
h_x = [point.x for point in hull]
|
||||||
|
h_y = [point.y for point in hull]
|
||||||
|
|
||||||
|
plt.plot(h_x, h_y, 'ro')
|
||||||
|
|
||||||
|
plt.scatter(x, y)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def display_line_only(points: Set[Point], slope: int, intercept: int, line_points: Set[Point]):
|
||||||
|
x = [point.x for point in points]
|
||||||
|
y = [point.y for point in points]
|
||||||
|
|
||||||
|
plt.scatter(x, y)
|
||||||
|
|
||||||
|
# Plot a line from slope and intercept
|
||||||
|
axes = plt.gca()
|
||||||
|
x_vals = np.array(axes.get_xlim())
|
||||||
|
y_vals = intercept + slope * x_vals
|
||||||
|
|
||||||
|
for point in line_points:
|
||||||
|
plt.plot(point.x, point.y, 'go')
|
||||||
|
|
||||||
|
plt.plot(x_vals, y_vals, '--')
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
class Side(Enum):
|
||||||
|
ON = auto()
|
||||||
|
ABOVE = auto()
|
||||||
|
BELOW = auto()
|
Loading…
Reference in New Issue
Block a user