This commit is contained in:
parent
e600f40c1a
commit
82a864e57f
@ -40,9 +40,6 @@ def untangle2(resx: list) :
|
|||||||
|
|
||||||
return order
|
return order
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Convert the result (edges from j to k like d_25 = edge between vertex 2 and vertex 5) into the list of indices corresponding to the landmarks
|
# Convert the result (edges from j to k like d_25 = edge between vertex 2 and vertex 5) into the list of indices corresponding to the landmarks
|
||||||
def untangle(resx: list) :
|
def untangle(resx: list) :
|
||||||
N = len(resx) # length of res
|
N = len(resx) # length of res
|
||||||
@ -102,7 +99,49 @@ def print_res(res: list, landmarks: list, P) :
|
|||||||
steps = path_length(P, abs(res.x))
|
steps = path_length(P, abs(res.x))
|
||||||
print("\nSteps walked : " + str(steps))
|
print("\nSteps walked : " + str(steps))
|
||||||
|
|
||||||
# Constraint to not have d14 and d41 simultaneously
|
|
||||||
|
# Checks for cases of circular symmetry in the result
|
||||||
|
def has_circle(resx: list) :
|
||||||
|
N = len(resx) # length of res
|
||||||
|
L = int(np.sqrt(N)) # number of landmarks. CAST INTO INT but should not be a problem because N = L**2 by def.
|
||||||
|
n_edges = resx.sum() # number of edges
|
||||||
|
|
||||||
|
|
||||||
|
nonzeroind = np.nonzero(resx)[0] # the return is a little funny so I use the [0]
|
||||||
|
|
||||||
|
nonzero_tup = np.unravel_index(nonzeroind, (L,L))
|
||||||
|
|
||||||
|
indx = nonzero_tup[0].tolist()
|
||||||
|
indy = nonzero_tup[1].tolist()
|
||||||
|
|
||||||
|
|
||||||
|
verts = []
|
||||||
|
|
||||||
|
for i, x in enumerate(indx) :
|
||||||
|
verts.append((x, indy[i]))
|
||||||
|
|
||||||
|
|
||||||
|
for vert in verts :
|
||||||
|
visited = []
|
||||||
|
visited.append(vert)
|
||||||
|
|
||||||
|
while len(visited) < n_edges + 1 :
|
||||||
|
|
||||||
|
try :
|
||||||
|
ind = indx.index(vert[1])
|
||||||
|
|
||||||
|
vert = (indx[ind], indy[ind])
|
||||||
|
|
||||||
|
if vert in visited :
|
||||||
|
return visited
|
||||||
|
else :
|
||||||
|
visited.append(vert)
|
||||||
|
except :
|
||||||
|
break
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Constraint to not have d14 and d41 simultaneously. Does not prevent circular symmetry with more elements
|
||||||
def break_sym(landmarks, A_ub, b_ub):
|
def break_sym(landmarks, A_ub, b_ub):
|
||||||
L = len(landmarks)
|
L = len(landmarks)
|
||||||
upper_ind = np.triu_indices(L,0,L)
|
upper_ind = np.triu_indices(L,0,L)
|
||||||
@ -125,6 +164,26 @@ def break_sym(landmarks, A_ub, b_ub):
|
|||||||
|
|
||||||
return A_ub, b_ub
|
return A_ub, b_ub
|
||||||
|
|
||||||
|
|
||||||
|
def prevent_circle(landmarks, A_ub, b_ub, circle) :
|
||||||
|
N = len(landmarks)
|
||||||
|
l = [0]*N*N
|
||||||
|
|
||||||
|
for index in circle :
|
||||||
|
x = index[0]
|
||||||
|
y = index[1]
|
||||||
|
l[x*N+y] = 1
|
||||||
|
|
||||||
|
A_ub = np.vstack((A_ub,l))
|
||||||
|
b_ub.append(len(circle)-1)
|
||||||
|
|
||||||
|
"""print("\n\nPREVENT CIRCLE")
|
||||||
|
for i in range(7):
|
||||||
|
print(l[i*7:i*7+7])
|
||||||
|
print("\n")"""
|
||||||
|
|
||||||
|
return A_ub, b_ub
|
||||||
|
|
||||||
# Constraint to respect max number of travels
|
# Constraint to respect max number of travels
|
||||||
def respect_number(landmarks, A_ub, b_ub):
|
def respect_number(landmarks, A_ub, b_ub):
|
||||||
h = []
|
h = []
|
||||||
@ -152,9 +211,9 @@ def respect_order(landmarks: list, A_eq, b_eq):
|
|||||||
A_eq = np.vstack((A_eq,l))
|
A_eq = np.vstack((A_eq,l))
|
||||||
b_eq.append(0)
|
b_eq.append(0)
|
||||||
|
|
||||||
for i in range(7):
|
"""for i in range(7):
|
||||||
print(l[i*7:i*7+7])
|
print(l[i*7:i*7+7])
|
||||||
print("\n")
|
print("\n")"""
|
||||||
|
|
||||||
return A_eq, b_eq
|
return A_eq, b_eq
|
||||||
|
|
||||||
@ -268,7 +327,19 @@ A_eq, b_eq = respect_order(landmarks, A_eq, b_eq) # Respect order o
|
|||||||
x_bounds = [(0, 1)] * len(c)
|
x_bounds = [(0, 1)] * len(c)
|
||||||
|
|
||||||
# Solve linear programming problem
|
# Solve linear programming problem
|
||||||
|
|
||||||
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3)
|
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3)
|
||||||
|
circle = has_circle(res.x)
|
||||||
|
|
||||||
|
while len(circle) != 0 :
|
||||||
|
print("The solution has a circular path. Not interpretable.")
|
||||||
|
print("Need to add constraints until no circle ")
|
||||||
|
|
||||||
|
A_ub, b_ub = prevent_circle(landmarks, A_ub, b_ub, circle)
|
||||||
|
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3)
|
||||||
|
circle = has_circle(res.x)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Raise error if no solution is found
|
# Raise error if no solution is found
|
||||||
if not res.success :
|
if not res.success :
|
||||||
|
Loading…
x
Reference in New Issue
Block a user