Fixed solution-selection and root-transformation bugs.
This commit is contained in:
parent
38c71c882b
commit
74386c1710
|
@ -927,5 +927,18 @@ class ClusterSolver(Notifier):
|
|||
## raise "cluster determined by more than one method"
|
||||
## return result
|
||||
|
||||
|
||||
##def _all_sources_constraint_in_cluster(self, constraint, cluster):
|
||||
## if not self._contains_constraint(cluster, constraint):
|
||||
## return Set()
|
||||
## elif self._is_atomic(cluster):
|
||||
## return Set([cluster])
|
||||
## else:
|
||||
## method = self._determining_method(cluster)
|
||||
## sources = Set()
|
||||
## for inp in method.input_clusters():
|
||||
## sources.union_update(self._all_sources_constraint_in_cluster(constraint, inp))
|
||||
## return sources
|
||||
|
||||
# class ClusterSolver
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ class ClusterSolver3D(ClusterSolver):
|
|||
|
||||
# overriding ClusterSolver.set_root
|
||||
def set_root(self, cluster):
|
||||
"""Set root cluster, used for positionig and orienting the solutions"""
|
||||
diag_print("set root "+str(self.rootcluster), "clsolver3D")
|
||||
if self.rootcluster != None:
|
||||
oldrootvar = rootname(self.rootcluster)
|
||||
|
@ -99,18 +100,7 @@ class ClusterSolver3D(ClusterSolver):
|
|||
|
||||
# ------------ INTERNALLY USED METHODS --------
|
||||
|
||||
def _all_sources_constraint_in_cluster(self, constraint, cluster):
|
||||
if not self._contains_constraint(cluster, constraint):
|
||||
return Set()
|
||||
elif self._is_atomic(cluster):
|
||||
return Set([cluster])
|
||||
else:
|
||||
method = self._determining_method(cluster)
|
||||
sources = Set()
|
||||
for inp in method.input_clusters():
|
||||
sources.union_update(self._all_sources_constraint_in_cluster(constraint, inp))
|
||||
return sources
|
||||
|
||||
|
||||
# --------------
|
||||
# search methods
|
||||
# --------------
|
||||
|
@ -212,15 +202,19 @@ class ClusterSolver3D(ClusterSolver):
|
|||
self._add_cluster(output)
|
||||
self._add_method(merge)
|
||||
# remove input clusters from top_level
|
||||
if not (hasattr(merge,"noremove") and merge.noremove == True):
|
||||
merge.restore_toplevel = [] # make restore list in method
|
||||
for cluster in merge.input_clusters():
|
||||
if num_constraints(cluster.intersection(output)) >= num_constraints(cluster):
|
||||
diag_print("remove from top-level: "+str(cluster),"clsolver3D")
|
||||
self._rem_top_level(cluster)
|
||||
merge.restore_toplevel.append(cluster)
|
||||
else:
|
||||
diag_print("keep top-level: "+str(cluster),"clsolver3D")
|
||||
merge.restore_toplevel = [] # make restore list in method
|
||||
for cluster in merge.input_clusters():
|
||||
# do not remove rigids from toplevel if method does not consider root
|
||||
if isinstance(cluster, Rigid):
|
||||
if hasattr(merge,"noremove") and merge.noremove == True:
|
||||
continue
|
||||
# remove input clusters when all its constraints are in output cluster
|
||||
if num_constraints(cluster.intersection(output)) >= num_constraints(cluster):
|
||||
diag_print("remove from top-level: "+str(cluster),"clsolver3D")
|
||||
self._rem_top_level(cluster)
|
||||
merge.restore_toplevel.append(cluster)
|
||||
else:
|
||||
diag_print("keep top-level: "+str(cluster),"clsolver3D")
|
||||
# add method to determine root-variable
|
||||
self._add_root_method(merge.input_clusters(),merge.outputs()[0])
|
||||
# add solution selection methods
|
||||
|
@ -544,7 +538,7 @@ class DeriveDAD(ClusterMethod):
|
|||
return solutions
|
||||
|
||||
class DeriveADD(ClusterMethod):
|
||||
"""Represents a merging of one distance and to distances"""
|
||||
"""Represents a merging of one angle and two distances"""
|
||||
def __init__(self, map):
|
||||
# check inputs
|
||||
self.a_cab = map["$a_cab"]
|
||||
|
@ -636,7 +630,7 @@ class DeriveAA(ClusterMethod):
|
|||
return solutions
|
||||
|
||||
class MergeSR(ClusterMethod):
|
||||
"""Merge a Rigid from a Scalabe and a Rigid sharing two points"""
|
||||
"""Merge a Scalabe and a Rigid sharing two points"""
|
||||
def __init__(self, map):
|
||||
# check inputs
|
||||
in1 = map["$r"]
|
||||
|
|
|
@ -7,6 +7,7 @@ from multimethod import MultiVariable
|
|||
class Distance:
|
||||
"""A Distance represents a known distance"""
|
||||
|
||||
|
||||
def __init__(self, a, b):
|
||||
"""Create a new Distance
|
||||
|
||||
|
@ -15,7 +16,7 @@ class Distance:
|
|||
b - point variable
|
||||
"""
|
||||
self.vars = (a,b)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "dist("\
|
||||
+str(self.vars[0])+","\
|
||||
|
@ -63,6 +64,12 @@ class Angle:
|
|||
|
||||
class Cluster(MultiVariable):
|
||||
"""A set of points, satisfying some constaint"""
|
||||
|
||||
staticcounter = 0
|
||||
|
||||
def __init__(self):
|
||||
Cluster.staticcounter += 1
|
||||
self.creationtime = Cluster.staticcounter
|
||||
|
||||
def intersection(self, other):
|
||||
shared = Set(self.vars).intersection(other.vars)
|
||||
|
@ -125,7 +132,8 @@ class Rigid(Cluster):
|
|||
|
||||
keyword args:
|
||||
vars - list of variables
|
||||
"""
|
||||
"""
|
||||
Cluster.__init__(self)
|
||||
self.vars = ImmutableSet(vars)
|
||||
self.overconstrained = False
|
||||
|
||||
|
@ -153,6 +161,7 @@ class Hedgehog(Cluster):
|
|||
cvar - center variable
|
||||
xvars - list of variables
|
||||
"""
|
||||
Cluster.__init__(self)
|
||||
self.cvar = cvar
|
||||
if len(xvars) < 2:
|
||||
raise StandardError, "hedgehog must have at least three variables"
|
||||
|
@ -182,6 +191,7 @@ class Balloon(Cluster):
|
|||
keyword args:
|
||||
vars - collection of PointVar's
|
||||
"""
|
||||
Cluster.__init__(self)
|
||||
if len(variables) < 3:
|
||||
raise StandardError, "balloon must have at least three variables"
|
||||
self.vars = ImmutableSet(variables)
|
||||
|
|
|
@ -328,9 +328,9 @@ class GeometricSolver (Listener):
|
|||
map[geocluster].append(drcluster)
|
||||
|
||||
for geocluster in geoclusters:
|
||||
# pick drcluster with fewest solutions
|
||||
# pick newest drcluster
|
||||
drclusters = map[geocluster]
|
||||
drcluster = min(drclusters, key=lambda c: len(self.dr.get(drcluster)))
|
||||
drcluster = max(drclusters, key=lambda c: c.creationtime)
|
||||
# determine solutions
|
||||
solutions = self.dr.get(drcluster)
|
||||
underconstrained = False
|
||||
|
|
10
test/test.py
10
test/test.py
|
@ -739,11 +739,11 @@ def test(problem, use_prototype=True):
|
|||
#diag_select(".*")
|
||||
print "problem:"
|
||||
print problem
|
||||
print "use_prototype=",use_prototype
|
||||
solver = GeometricSolver(problem, use_prototype)
|
||||
#solver.set_prototype_selection(use_prototype)
|
||||
#print "drplan:"
|
||||
#print solver.dr
|
||||
#print "number of top-level rigids:",len(solver.dr.top_level())
|
||||
print "drplan:"
|
||||
print solver.dr
|
||||
print "top-level rigids:",solver.dr.top_level()
|
||||
result = solver.get_result()
|
||||
print "result:"
|
||||
print result
|
||||
|
@ -751,6 +751,7 @@ def test(problem, use_prototype=True):
|
|||
check = True
|
||||
if len(result.solutions) == 0:
|
||||
check = False
|
||||
diag_select("GeometricProblem.verify")
|
||||
for sol in result.solutions:
|
||||
print "solution:",sol
|
||||
check = check and problem.verify(sol)
|
||||
|
@ -758,7 +759,6 @@ def test(problem, use_prototype=True):
|
|||
print "all solutions valid"
|
||||
else:
|
||||
print "INVALID"
|
||||
|
||||
|
||||
# ----- what to test today -------
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user