Example #1
0
 def test_arc_will_restore_all_domains_when_not_given_the_last_queen(self):
     ac = ArcConsistency(Arcs(4))
     problem = Variables(4)
     problem.queens[0].value = 1
     problem.queens[1].value = 3
     ac.arcConsistent(problem)
     self.assertEqual(set([1, 2, 3, 4]), problem.queens[1].domain)
     self.assertEqual(3, problem.queens[1].value)
Example #2
0
 def test_arc_will_not_backtrack_too_far_when_it_sees_a_failure(self):
     ac = ArcConsistency(Arcs(4))
     problem = Variables(4)
     problem.queens[0].value = 2
     problem.queens[3].value = 4
     ac.arcConsistent(problem, problem.queens[3])
     self.assertEqual(set([3]), problem.queens[3].domain)
     self.assertEqual(-1, problem.queens[3].value)
Example #3
0
 def setUp(self):
     self.ac = ArcConsistency(Arcs(8))
Example #4
0
class Line:
    def __init__(self, Q):
        self.arcs = Arcs(Q)

    def arc(self, current_arc, last=False):
        n = len(current_arc)
        if last and not len(self.line_arcs) and n == 1:
            point = current_arc[0]
            index = self.arcs.get_index(point)
            if len(index):
                self.line_arcs.append(index[0])
            else:
                index.append(self.arcs.length)
                self.line_arcs.append(index[0])
                self.arcs.push(current_arc)
        elif n > 1:
            self.line_arcs.append(self.arcs.check(current_arc))

    def line(self, points, opened):
        self.line_arcs = []
        n = len(points)
        current_arc = Strut()
        k = 0
        p = False
        t = False
        if not opened:
            points.pop()
            n -= 1
        while k < n:
            t = self.arcs.peak(points[k])
            if opened:
                break
            if p and not mysterious_line_test(p, t):
                tInP = all(map(lambda line: line in p, t))
                pInT = all(map(lambda line: line in t, p))
                if tInP and not pInT:
                    k -= 1
                break
            p = t
            k += 1
        # If no shared starting point is found for closed lines, rotate to minimum.
        if k == n and isinstance(p, list) and len(p) > 1:
            point0 = points[0]
            i = 2
            k = 0
            while i < n:
                point = points[i]
                if point_compare(point0, point) > 0:
                    point0 = point
                    k = i
                i += 1
        i = -1
        if opened:
            m = n - 1
        else:
            m = n
        while i < m:
            i += 1
            point = points[(i + k) % n]
            p = self.arcs.peak(point)
            if not mysterious_line_test(p, t):
                tInP = all(map(lambda line: line in p, t))
                pInT = all(map(lambda line: line in t, p))
                if tInP:
                    current_arc.append(point)
                self.arc(current_arc)
                if not tInP and not pInT and len(current_arc):
                    self.arc(Strut([current_arc[-1], point]))
                if pInT and len(current_arc):
                    current_arc = Strut([current_arc[-1]])
                else:
                    current_arc = Strut()
            if not len(current_arc) or point_compare(current_arc[-1], point):
                current_arc.append(point)  # skip duplicate points
            t = p
        self.arc(current_arc, True)
        return self.line_arcs

    def line_closed(self, points):
        return self.line(points, False)

    def line_open(self, points):
        return self.line(points, True)

    def map_func(self, arc):
        if len(arc) == 2 and type(arc[0]) == type(1):
            arc = [arc]
        i = 1
        n = len(arc)
        point = arc[0]
        x1 = point[0]
        x2 = dx = y2 = dy = False
        y1 = point[1]
        points = [[int(x1), int(y1)]]
        while i < n:
            point = arc[i]
            if not is_point(point):
                i += 1
                continue
            x2 = point[0]
            y2 = point[1]
            dx = int(x2 - x1)
            dy = int(y2 - y1)
            if dx or dy:
                points.append([dx, dy])
                x1 = x2
                y1 = y2
            i += 1
        return points

    def get_arcs(self):
        return self.arcs.map(self.map_func)
Example #5
0
 def __init__(self, Q):
     self.arcs = Arcs(Q)
Example #6
0
 def setUp(self):
     self.gac = GlobalArcConsistency(Arcs(8))
Example #7
0
class Line:
    def __init__(self, Q):
        self.arcs = Arcs(Q)

    def matchForward(self, b, arthur):
        i = 0
        n = len(arthur)
        if len(b) != n:
            return False
        while i < n:
            if pointCompare(arthur[i], b[i]):
                return False
            i += 1
            self.lineArcs.append(b.index)
            return True

    def matchBackward(self, b, arthur):
        i = 0
        n = len(arthur)
        if len(b) != n:
            return False
        while i < n:
            if pointCompare(arthur[i], b[n - i - 1]):
                return False
            i += 1
        self.lineArcs.append(~b.index)
        return True

    def arc(self, alice, last=False):
        n = len(alice)
        if last and not len(self.lineArcs) and n == 1:
            point = alice[0]
            index = self.arcs.getIndex(point)
            if len(index):
                self.lineArcs.append(index[0])
            else:
                index.append(self.arcs.length)
                self.lineArcs.append(index[0])
                self.arcs.push(alice)
        elif n > 1:
            a0 = alice[0]
            a1 = alice[-1]
            point = a0 if pointCompare(a0, a1) < 0 else a1
            pointArcs = self.arcs.getPointArcs(point)
            if any(map(lambda x: self.matchForward(x, alice), pointArcs)):
                return
            if any(map(lambda x: self.matchBackward(x, alice), pointArcs)):
                return
            pointArcs.append(alice)
            alice.index = self.arcs.length
            self.lineArcs.append(alice.index)
            self.arcs.push(alice)

    def line(self, points, opened):
        self.lineArcs = []
        n = len(points)
        arthur = strut()
        k = 1
        p = False
        t = False
        if not opened:
            points.pop()
            n -= 1
        while k < n:
            t = self.arcs.peak(points[k])
            if opened:
                break
            if p and not linesEqual(p, t):
                tInP = all(map(lambda line: line in p, t))
                pInT = all(map(lambda line: line in t, p))
                if tInP and not pInT:
                    k -= 1
                break
            p = t
            k += 1
        # If no shared starting point is found for closed lines, rotate to minimum.
        if k == n and len(p) > 1:
            point0 = points[0]
            i = 2
            k = 0
            while i < n:
                point = points[i]
                if pointCompare(point0, point) > 0:
                    point0 = point
                    k = i
                i += 1
        i = 0
        if opened:
            m = n
        else:
            m = n + 1
        while i < m:
            i += 1
            point = points[(i + k) % n]
            p = self.arcs.peak(point)
            if not linesEqual(p, t):
                tInP = all(map(lambda line: line in p, t))
                pInT = all(map(lambda line: line in t, p))
                if tInP:
                    arthur.append(point)
                self.arc(arthur)
                if not tInP and not pInT:
                    self.arc(strut([arthur[-1], point]))
                if pInT and len(arthur):
                    arthur = strut([arthur[-1]])
                else:
                    arthur = strut()
            if not len(arthur) or pointCompare(arthur[-1], point):
                arthur.append(point)  # skip duplicate points
            t = p
        self.arc(arthur, True)
        return self.lineArcs

    def lineClosed(self, points):
        return self.line(points, False)

    def lineOpen(self, points):
        self.line(points, True)

    def mapFunc(self, arc):
        if len(arc) == 2 and type(arc[0]) == type(1):
            arc = [arc]
        i = 1
        n = len(arc)
        point = arc[0]
        x1 = point[0]
        x2 = dx = y2 = dy = False
        y1 = point[1]
        points = [[int(x1), int(y1)]]
        while i < n:
            point = arc[i]
            if not isPoint(point):
                i += 1
                continue
            x2 = point[0]
            y2 = point[1]
            dx = int(x2 - x1)
            dy = int(y2 - y1)
            if dx or dy:
                points.append([dx, dy])
                x1 = x2
                y1 = y2
            i += 1
        return points

    def getArcs(self):
        return self.arcs.map(self.mapFunc)
Example #8
0
 def test_global_arc_consistency_can_find_a_solution(self):
     problem = Variables(4)
     gac = GlobalArcConsistency(Arcs(4))
     gac.findSolution(problem)
     self.assertTrue(self.fourByFourSolution(problem.queens) or self.altFourByFourSolution(problem.queens))
Example #9
0
 def test_global_arc_consistency_can_find_a_larger_solution(self):
     problem = Variables(8)
     gac = GlobalArcConsistency(Arcs(8))
     gac.findSolution(problem)
     for queen in problem.queens:
         self.assertNotEqual(-1, queen.value)
Example #10
0
 def __init__(self,Q):
     self.arcs = Arcs(Q)
Example #11
0
class Line:
    def __init__(self,Q):
        self.arcs = Arcs(Q)
    def arc(self,current_arc, last=False):
        n = len(current_arc)
        if last and not len(self.line_arcs) and n == 1:
            point = current_arc[0]
            index = self.arcs.get_index(point)
            if len(index):
                self.line_arcs.append(index[0])
            else:
                index.append(self.arcs.length)
                self.line_arcs.append(index[0])
                self.arcs.push(current_arc)
        elif n > 1:
            self.line_arcs.append(self.arcs.check(current_arc))

    def line(self,points,opened):
        self.line_arcs = [];
        n = len(points)
        current_arc = Strut()
        k = 1
        p=False
        t=False
        if not opened:
            points.pop()
            n-=1
        while k < n:
            t = self.arcs.peak(points[k])
            if opened:
                break
            if p and not mysterious_line_test(p, t):
                tInP = all(map(lambda line:line in p,t))
                pInT = all(map(lambda line:line in t,p))
                if tInP and not pInT:
                    k-=1
                break
            p = t
            k+=1
        # If no shared starting point is found for closed lines, rotate to minimum.
        if k == n and isinstance(p,list) and len(p) > 1:
            point0 = points[0]
            i = 2
            k=0
            while i<n:
                point = points[i];
                if point_compare(point0, point) > 0:
                    point0 = point
                    k = i
                i+=1
        i = 0
        if opened:
            m = n
        else:
            m = n+1
        while i < m:
            i+=1
            point = points[(i + k) % n]
            p = self.arcs.peak(point)
            if not mysterious_line_test(p, t):
                tInP = all(map(lambda line: line in p,t))
                pInT = all(map(lambda line: line in t,p))
                if tInP:
                    current_arc.append(point);
                self.arc(current_arc)
                if not tInP and not pInT and len(current_arc):
                    self.arc(Strut([current_arc[-1], point]))
                if pInT and len(current_arc):
                    current_arc = Strut([current_arc[-1]])
                else:
                    current_arc = Strut();
            if not len(current_arc) or point_compare(current_arc[-1], point):
                current_arc.append(point) # skip duplicate points
            t = p
        self.arc(current_arc, True)
        return self.line_arcs
    def line_closed(self,points):
        return self.line(points,False)
    def line_open(self,points):
        return self.line(points,True)
    def map_func (self,arc):
        if len(arc)==2 and type(arc[0])==type(1):
            arc= [arc]
        i = 1
        n = len(arc)
        point = arc[0]
        x1 = point[0]
        x2= dx =y2 = dy=False
        y1 = point[1]
        points = [[int(x1), int(y1)]]
        while i < n:
            point = arc[i]
            if not is_point(point):
                i+=1
                continue
            x2 = point[0]
            y2 = point[1]
            dx = int(x2 - x1)
            dy = int(y2 - y1)
            if dx or dy:
                points.append([dx, dy])
                x1 = x2
                y1 = y2
            i+=1
        return points
    def get_arcs (self):
        return self.arcs.map(self.map_func)
Example #12
0
class Line:
	def __init__(self,Q):
		self.arcs = Arcs(Q)
	def matchForward(self,b,arthur):
		i = 0
		n = len(arthur)
		if len(b) != n:
			return False
		while i < n:
			if pointCompare(arthur[i], b[i]):
				return False;
			i+=1
			self.lineArcs.append(b.index)
			return True;
	def matchBackward(self,b,arthur):
		i = 0
		n = len(arthur)
		if len(b) != n:
			return False
		while i<n:
			if pointCompare(arthur[i], b[n - i - 1]):
				return False
			i+=1
		self.lineArcs.append(~b.index)
		return True
	def arc(self,alice, last=False):
		n = len(alice)
		if last and not len(self.lineArcs) and n == 1:
			point = alice[0]
			index = self.arcs.getIndex(point)
			if len(index):
				self.lineArcs.append(index[0])
			else:
				index.append(self.arcs.length)
				self.lineArcs.append(index[0])
				self.arcs.push(alice)
		elif n > 1:
			a0 = alice[0]
			a1 = alice[-1]
			point = a0 if pointCompare(a0, a1) < 0 else a1
			pointArcs = self.arcs.getPointArcs(point)
			if any(map(lambda x:self.matchForward(x,alice),pointArcs)):
				return
			if any(map(lambda x:self.matchBackward(x,alice),pointArcs)):
				return
			pointArcs.append(alice)
			alice.index=self.arcs.length
			self.lineArcs.append(alice.index)
			self.arcs.push(alice)
	def line(self,points,opened):
		self.lineArcs = [];
		n = len(points)
		arthur = strut()
		k = 1
		p=False
		t=False
		if not opened:
			points.pop()
			n-=1
		while k < n:
			t = self.arcs.peak(points[k])
			if opened:
				break
			if p and not linesEqual(p, t):
				tInP = all(map(lambda line:line in p,t))
				pInT = all(map(lambda line:line in t,p))
				if tInP and not pInT:
					k-=1
				break
			p = t
			k+=1
		# If no shared starting point is found for closed lines, rotate to minimum.
		if k == n and len(p) > 1:
			point0 = points[0]
			i = 2
			k=0
			while i<n:
				point = points[i];
				if pointCompare(point0, point) > 0:
					point0 = point
					k = i
				i+=1
		i = 0
		if opened:
			m = n
		else:
			m = n+1
		while i < m:
			i+=1
			point = points[(i + k) % n]
			p = self.arcs.peak(point)
			if not linesEqual(p, t):
				tInP = all(map(lambda line: line in p,t))
				pInT = all(map(lambda line: line in t,p))
				if tInP:
					arthur.append(point);
				self.arc(arthur)
				if not tInP and not pInT:
					self.arc(strut([arthur[-1], point]))
				if pInT and len(arthur):
					arthur = strut([arthur[-1]])
				else:
					arthur = strut();
			if not len(arthur) or pointCompare(arthur[-1], point):
				arthur.append(point) # skip duplicate points
			t = p
		self.arc(arthur, True)
		return self.lineArcs
	def lineClosed(self,points):
		return self.line(points,False)
	def lineOpen(self,points):
		self.line(points,True)
	def mapFunc (self,arc):
		if len(arc)==2 and type(arc[0])==type(1):
			arc= [arc]
		i = 1;
		n = len(arc)
		point = arc[0]
		x1 = point[0]
		x2= dx =y2 = dy=False
		y1 = point[1]
		points = [[int(x1), int(y1)]]
		while i < n:
			point = arc[i]
			if not isPoint(point):
				i+=1
				continue
			x2 = point[0]
			y2 = point[1]
			dx = int(x2 - x1)
			dy = int(y2 - y1)
			if dx or dy:
				points.append([dx, dy])
				x1 = x2
				y1 = y2
			i+=1
		return points
	def getArcs (self):
		return self.arcs.map(self.mapFunc)
Example #13
0
 def setUp(self):
     self.constraints = Arcs(8)
     self.variables = Variables(8)
Example #14
0
class Arc_Tests(unittest.TestCase):
    def setUp(self):
        self.constraints = Arcs(8)
        self.variables = Variables(8)

    def test_there_are_two_arcs_for_each_constraint(self):
        self.assertEqual(112, len(self.constraints.set))

    def test_constraints_can_detect_two_queens_in_the_same_diagonal(self):
        self.variables.queens[0].value = 4
        self.variables.queens[3].value = 7
        self.assertEqual(False, self.constraints.verify(self.variables))

    def test_constraints_can_detect_two_queens_in_the_opposing_diagonals(self):
        self.variables.queens[4].value = 6
        self.variables.queens[7].value = 3
        self.assertEqual(False, self.constraints.verify(self.variables))

    def test_constraints_can_detect_three_queens_in_the_same_diagonal(self):
        self.variables.queens[0].value = 4
        self.variables.queens[2].value = 6
        self.variables.queens[3].value = 7
        self.assertEqual(False, self.constraints.verify(self.variables))

    def test_constraints_can_detect_two_queens_in_the_same_rows(self):
        self.variables.queens[0].value = 1
        self.variables.queens[7].value = 1
        self.assertEqual(False, self.constraints.verify(self.variables))

    def test_constraints_can_detect_three_queens_in_the_same_rows(self):
        self.variables.queens[0].value = 4
        self.variables.queens[1].value = 4
        self.variables.queens[2].value = 4
        self.assertEqual(False, self.constraints.verify(self.variables))

    def test_constraints_will_allow_unassigned_values_to_pass_constraints(
            self):
        self.variables.queens[0].value = 1
        self.variables.queens[1].value = 3
        self.assertEqual(True, self.constraints.verify(self.variables))

    def test_contraints_will_prune_domains(self):
        self.variables.queens[0].value = 1
        self.constraints.wipeout(self.variables, self.variables.queens[0])
        self.variables.queens[1].value = 3
        self.constraints.wipeout(self.variables, self.variables.queens[1])
        self.assertEqual(set([5, 6, 7, 8]), self.variables.queens[2].domain)
        self.assertEqual(set([2, 6, 7, 8]), self.variables.queens[3].domain)
        self.assertEqual(set([2, 4, 7, 8]), self.variables.queens[4].domain)
        self.assertEqual(set([2, 4, 5, 6, 7]), self.variables.queens[7].domain)

    def test_contraints_will_return_nothing_when_assigned_values_wipeout_a_domain(
            self):
        self.variables.queens[0].value = 2
        self.constraints.wipeout(self.variables, self.variables.queens[0])
        self.variables.queens[1].value = 4
        self.constraints.wipeout(self.variables, self.variables.queens[1])
        self.variables.queens[2].value = 1
        self.constraints.wipeout(self.variables, self.variables.queens[2])
        self.variables.queens[3].value = 3
        self.constraints.wipeout(self.variables, self.variables.queens[3])
        self.variables.queens[4].value = 5
        self.assertEqual(
            None,
            self.constraints.wipeout(self.variables, self.variables.queens[4]))

    def test_constraints_will_return_the_pruned_values(self):
        self.variables.queens[0].value = 1
        values = self.constraints.wipeout(self.variables,
                                          self.variables.queens[0])
        self.assertItemsEqual([(3, 1), (2, 3), (7, 8), (2, 1), (7, 1), (5, 6),
                               (4, 1), (4, 5), (5, 1), (1, 2), (3, 4), (6, 1),
                               (1, 1), (6, 7)], values)

    def test_constraints_can_restore_domains(self):
        self.variables.queens[0].value = 1
        values = self.constraints.wipeout(self.variables,
                                          self.variables.queens[0])
        self.constraints.restore(self.variables, values)
        self.assertEqual(set([1, 2, 3, 4, 5, 6, 7, 8]),
                         self.variables.queens[0].domain)
        self.assertEqual(set([1, 2, 3, 4, 5, 6, 7, 8]),
                         self.variables.queens[1].domain)
        self.assertEqual(set([1, 2, 3, 4, 5, 6, 7, 8]),
                         self.variables.queens[7].domain)