Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Possible improvmeents #62

Closed
Closed
@maciejlibraryx

Description

@maciejlibraryx

Hi!

A few possible improvements (overall I got over 100x speed improvement over your vanilla code).
a) mapping all variable names to integers (internally). This depends, but for me it gave up to 10x speedup.
b) Changing a few things in the solvers. I copy an example of what I did. It's rather simple optimization of taking some of the repeated code out of the loops. Unless I missed it there, there are no dependencies there. (I checked the correctness of the code). This gives around 4x speedup
c) Switching from dicts to lists inside the solvers (havent done that yet). Seems its gonna be possible in a few places. At the moment dictionary copy method in "yield assignments.copy()" takes bulk of the time.

Hope it helps!

class OptimizedSolver(Solver):
"""
Problem solver with backtracking capabilities

Examples:>>> result = [[('a', 1), ('b', 2)],...           [('a', 1), ('b', 3)],...           [('a', 2), ('b', 3)]]>>> problem = Problem(BacktrackingSolver())>>> problem.addVariables(["a", "b"], [1, 2, 3])>>> problem.addConstraint(lambda a, b: b > a, ["a", "b"])>>> solution = problem.getSolution()>>> sorted(solution.items()) in resultTrue>>> for solution in problem.getSolutionIter():...     sorted(solution.items()) in resultTrueTrueTrue>>> for solution in problem.getSolutions():...     sorted(solution.items()) in resultTrueTrueTrue"""def __init__(self, forwardcheck=True):    """    @param forwardcheck: If false forward checking will not be requested                         to constraints while looking for solutions                         (default is true)    @type  forwardcheck: bool    """    self._forwardcheck = forwardcheckdef getSolutionIter(self, domains, constraints, vconstraints, lst):    forwardcheck = self._forwardcheck    assignments = {}    queue = []    while True:        # Mix the Degree and Minimum Remaing Values (MRV) heuristics        for variable in lst:            if variable not in assignments:                # Found unassigned variable                values = domains[variable][:]                if forwardcheck:                    pushdomains = [                        domains[x]                        for x in domains                        if x not in assignments and x != variable                    ]                else:                    pushdomains = None                break        else:            # No unassigned variables. We've got a solution. Go back            # to last variable, if there's one.            yield assignments.copy()            if not queue:                return            variable, values, pushdomains = queue.pop()            if pushdomains:                for domain in pushdomains:                    domain.popState()        while True:            # We have a variable. Do we have any values left?            if not values:                # No. Go back to last variable, if there's one.                del assignments[variable]                while queue:                    variable, values, pushdomains = queue.pop()                    if pushdomains:                        for domain in pushdomains:                            domain.popState()                    if values:                        break                    del assignments[variable]                else:                    return            # Got a value. Check it.            assignments[variable] = values.pop()            if pushdomains:                for domain in pushdomains:                    domain.pushState()            for constraint, variables in vconstraints[variable]:                if not constraint(variables, domains, assignments, pushdomains):                    # Value is not good.                    break            else:                break            if pushdomains:                for domain in pushdomains:                    domain.popState()        # Push state before looking for next variable.        queue.append((variable, values, pushdomains))    raise RuntimeError("Can't happen")def getSolutions(self, domains, constraints, vconstraints):    lst = [        (-len(vconstraints[variable]), len(domains[variable]), variable)        for variable in domains    ]    lst.sort()    return list(self.getSolutionIter(domains, constraints, vconstraints, [c for a,b,c in lst]))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp