This commit is contained in:
Casper 2018-10-09 19:26:55 +02:00
parent 8a507c08fa
commit 26dfb6d305
No known key found for this signature in database
GPG Key ID: B1156723DB3BDDA8
5 changed files with 146 additions and 311 deletions

View File

@ -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]

View File

@ -1,15 +1,4 @@
import random from util import gen_point, Side, Point, display
from collections import namedtuple
from enum import Enum, auto
import matplotlib.pyplot as plt
Point = namedtuple('Point', ['x', 'y'])
class Side(Enum):
ON = auto()
ABOVE = auto()
BELOW = auto()
def sidedness(p1, p2, p3, eps=0.0000001): def sidedness(p1, p2, p3, eps=0.0000001):
@ -40,16 +29,6 @@ p3 = Point(5, 2)
# print(sidedness(p1, p2, p3)) # print(sidedness(p1, p2, p3))
def genPoint():
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 graham_scan(points): def graham_scan(points):
# A funky issue where both a and b become negative in the sidedness test causes us to have to use # A funky issue where both a and b become negative in the sidedness test causes us to have to use
@ -78,20 +57,7 @@ def graham_scan(points):
return UH, LH return UH, LH
p = [genPoint() for _ in range(30)] p = [gen_point() for _ in range(30)]
UH, LH = graham_scan(p) UH, LH = graham_scan(p)
x = [point.x for point in p] display(p, {*UH, *LH})
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()

170
h2/mbc.py
View File

@ -1,66 +1,11 @@
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)
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 # 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
@ -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}

View File

@ -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
View 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()