Skip to content

quast_decisiontree.nodes.algorithm_select

quast_decisiontree.nodes.algorithm_select

map_algo_to_next_node module-attribute

map_algo_to_next_node = dict(
    BruteForce="BruteForceSetupNode",
    TabuSolver="TabuSetupNode",
    LRQAOA="SelectLayersNode",
    QrispQAOA="SelectLayersNode",
    QrispVQE="QrispAnsatzNode",
    BaseQAOA="SelectLayersNode",
    QAOA="SelectLayersNode",
    VQE="QrispAnsatzNode",
)

map_algo_to_setup_node module-attribute

map_algo_to_setup_node = dict(
    BruteForce="BruteForceSetupNode",
    TabuSolver="TabuSetupNode",
    LRQAOA="LRQAOASetupNode",
    QrispQAOA="QrispQAOASetupNode",
    QrispVQE="QrispVQESetupNode",
    BaseQAOA="QrispQAOASetupNode",
    QAOA="QrispQAOASetupNode",
    VQE="QrispVQESetupNode",
)

logger module-attribute

logger = logging.getLogger('dt_logger')

AlgorithmSelectionNode

Bases: Node

allows the user to select an algorithm

Modifications at runtime: - algorithm - {algorithm_name} : name of the algorithm to run

Source code in src/quast_decisiontree/nodes/algorithm_select.py
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
class AlgorithmSelectionNode(Node):
    """allows the user to select an algorithm

    Modifications at runtime:
    - algorithm
        - {algorithm_name} : name of the algorithm to run
    """

    _known_children = list(map_algo_to_next_node.values())
    _path_keys = dict(algorithm=PathKey(str, list(map_algo_to_next_node.keys())))

    def __init__(self, children: list, options: list | None = None) -> None:
        super().__init__(
            requires="problem_class",
            creates=["algorithm", "algorithm_setup_node"],
            children=children,
        )
        self.options, self.next_nodes = self._find_options()
        if options is not None:
            self.options = {key: val for key, val in self.options.items() if key in options}
            missing = [option for option in options if option not in self.options]
            if missing:
                logger.warning("No algorithm configured for options %r", missing)

        self.query = MultiChoiceQuery(
            question="Which algorithm do you want to use?",
            answers=dict(self.options),
            name="algorithm",
        )

    def _find_options(self) -> tuple[dict, dict]:
        names = [name for name, node in map_algo_to_next_node.items() if node in self.children]
        next_nodes = {name: map_algo_to_next_node[name] for name in names}
        return {name: name for name in names}, next_nodes

    def execute(self, problem_data: dict, path_info: dict) -> dict:
        """prompts for an algorithm to run"""
        if os.environ.get("QDT_MODE") in ["auto", "accept"]:
            self.query.set_default(recommend_algorithm(problem_data))

        if path_info.get("algorithm") is not None:
            problem_data["algorithm"] = path_info["algorithm"]
        else:
            problem_data["algorithm"] = self.query.input()
            path_info["algorithm"] = problem_data["algorithm"]

        problem_data["algorithm_setup_node"] = map_algo_to_setup_node[problem_data["algorithm"]]
        return dict(algorithm=problem_data["algorithm"])

    def next_node(self, next_node_info: dict) -> str:
        try:
            return self.next_nodes[next_node_info["algorithm"]]
        except KeyError as exc:
            raise ValueError("No valid algorithm selected.") from exc

options instance-attribute

options = {
    key: val
    for key, val in (self.options.items())
    if key in options
}

query instance-attribute

query = MultiChoiceQuery(
    question="Which algorithm do you want to use?",
    answers=dict(self.options),
    name="algorithm",
)

__init__

__init__(children, options=None)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def __init__(self, children: list, options: list | None = None) -> None:
    super().__init__(
        requires="problem_class",
        creates=["algorithm", "algorithm_setup_node"],
        children=children,
    )
    self.options, self.next_nodes = self._find_options()
    if options is not None:
        self.options = {key: val for key, val in self.options.items() if key in options}
        missing = [option for option in options if option not in self.options]
        if missing:
            logger.warning("No algorithm configured for options %r", missing)

    self.query = MultiChoiceQuery(
        question="Which algorithm do you want to use?",
        answers=dict(self.options),
        name="algorithm",
    )

execute

execute(problem_data, path_info)

prompts for an algorithm to run

Source code in src/quast_decisiontree/nodes/algorithm_select.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
def execute(self, problem_data: dict, path_info: dict) -> dict:
    """prompts for an algorithm to run"""
    if os.environ.get("QDT_MODE") in ["auto", "accept"]:
        self.query.set_default(recommend_algorithm(problem_data))

    if path_info.get("algorithm") is not None:
        problem_data["algorithm"] = path_info["algorithm"]
    else:
        problem_data["algorithm"] = self.query.input()
        path_info["algorithm"] = problem_data["algorithm"]

    problem_data["algorithm_setup_node"] = map_algo_to_setup_node[problem_data["algorithm"]]
    return dict(algorithm=problem_data["algorithm"])

next_node

next_node(next_node_info)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
108
109
110
111
112
def next_node(self, next_node_info: dict) -> str:
    try:
        return self.next_nodes[next_node_info["algorithm"]]
    except KeyError as exc:
        raise ValueError("No valid algorithm selected.") from exc

SelectLayersNode

Bases: Node

Select the number of layers of the algorithm.

Modifications at runtime: - reps : - {int} : number of layers

Source code in src/quast_decisiontree/nodes/algorithm_select.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class SelectLayersNode(Node):
    """Select the number of layers of the algorithm.

    Modifications at runtime:
    - reps :
        - {int} : number of layers
    """

    _known_children = ["QrispMixerNode", "LRSetDeltaNode", "SelectOptimizerNode"]
    _path_keys = dict(reps=PathKey(int))

    def __init__(self, children):
        super().__init__(creates="reps", requires=["algorithm"], children=children)
        self.query = IntQuery("How many layers should the algorithm have?", name="reps", default=3)

    def execute(self, problem_data: dict, path_info: dict) -> dict:
        problem_data["reps"] = path_info.get("reps")
        if problem_data["reps"] is None:
            problem_data["reps"] = self.query.input()

        path_info["reps"] = problem_data["reps"]

        return dict(algorithm=problem_data["algorithm"])

    def next_node(self, next_node_info: dict) -> str:
        algorithm = next_node_info["algorithm"]
        if algorithm == "BaseQAOA":
            return "SelectOptimizerNode"
        elif algorithm == "LRQAOA":
            return "LRSetDeltaNode"
        elif algorithm in ["QrispQAOA", "QAOA"]:
            return "QrispMixerNode"
        else:
            raise ValueError(f"SelectLayersNode has no successor for algorithm {algorithm!r}.")

query instance-attribute

query = IntQuery(
    "How many layers should the algorithm have?",
    name="reps",
    default=3,
)

__init__

__init__(children)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
126
127
128
def __init__(self, children):
    super().__init__(creates="reps", requires=["algorithm"], children=children)
    self.query = IntQuery("How many layers should the algorithm have?", name="reps", default=3)

execute

execute(problem_data, path_info)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
130
131
132
133
134
135
136
137
def execute(self, problem_data: dict, path_info: dict) -> dict:
    problem_data["reps"] = path_info.get("reps")
    if problem_data["reps"] is None:
        problem_data["reps"] = self.query.input()

    path_info["reps"] = problem_data["reps"]

    return dict(algorithm=problem_data["algorithm"])

next_node

next_node(next_node_info)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
139
140
141
142
143
144
145
146
147
148
def next_node(self, next_node_info: dict) -> str:
    algorithm = next_node_info["algorithm"]
    if algorithm == "BaseQAOA":
        return "SelectOptimizerNode"
    elif algorithm == "LRQAOA":
        return "LRSetDeltaNode"
    elif algorithm in ["QrispQAOA", "QAOA"]:
        return "QrispMixerNode"
    else:
        raise ValueError(f"SelectLayersNode has no successor for algorithm {algorithm!r}.")

LRSetDeltaNode

Bases: Node

sets the delta for a LR circuit

Modifications at runtime: - "delta_gamma" (float): sets the delta_gamma of LR-QAOA - "delta_beta" (float): sets the delta_beta of LR-QAOA

Source code in src/quast_decisiontree/nodes/algorithm_select.py
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
class LRSetDeltaNode(Node):
    """sets the delta for a LR circuit

    Modifications at runtime:
    - "delta_gamma" (float): sets the delta_gamma of LR-QAOA
    - "delta_beta" (float): sets the delta_beta of LR-QAOA
    """

    _path_keys = dict(delta_gamma=PathKey(float), delta_beta=PathKey(float))

    def __init__(self, children):
        super().__init__(creates=["delta_gamma", "delta_beta"], requires=[], children=children)
        self.query_gamma = FloatQuery(
            "How large should the delta_gamma parameter of LR-QAOA be?",
            name="delta_gamma",
            default=0.5,
        )
        self.query_beta = FloatQuery(
            "How large should the delta_beta parameter of LR-QAOA be?",
            name="delta_beta",
            default=0.5,
        )
        self.queries = QueryTree(queries=[self.query_gamma, self.query_beta])

    def execute(self, problem_data: dict, path_info: dict) -> dict:
        problem_data["delta_gamma"] = path_info.get("delta_gamma")
        problem_data["delta_beta"] = path_info.get("delta_beta")
        if problem_data["delta_gamma"] is None:
            problem_data["delta_gamma"] = self.query_gamma.input()
        if problem_data["delta_beta"] is None:
            problem_data["delta_beta"] = self.query_beta.input()

        path_info["delta_gamma"] = problem_data["delta_gamma"]
        path_info["delta_beta"] = problem_data["delta_beta"]

        return dict()

query_gamma instance-attribute

query_gamma = FloatQuery(
    "How large should the delta_gamma parameter of LR-QAOA be?",
    name="delta_gamma",
    default=0.5,
)

query_beta instance-attribute

query_beta = FloatQuery(
    "How large should the delta_beta parameter of LR-QAOA be?",
    name="delta_beta",
    default=0.5,
)

queries instance-attribute

queries = QueryTree(
    queries=[self.query_gamma, self.query_beta]
)

__init__

__init__(children)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
161
162
163
164
165
166
167
168
169
170
171
172
173
def __init__(self, children):
    super().__init__(creates=["delta_gamma", "delta_beta"], requires=[], children=children)
    self.query_gamma = FloatQuery(
        "How large should the delta_gamma parameter of LR-QAOA be?",
        name="delta_gamma",
        default=0.5,
    )
    self.query_beta = FloatQuery(
        "How large should the delta_beta parameter of LR-QAOA be?",
        name="delta_beta",
        default=0.5,
    )
    self.queries = QueryTree(queries=[self.query_gamma, self.query_beta])

execute

execute(problem_data, path_info)
Source code in src/quast_decisiontree/nodes/algorithm_select.py
175
176
177
178
179
180
181
182
183
184
185
186
def execute(self, problem_data: dict, path_info: dict) -> dict:
    problem_data["delta_gamma"] = path_info.get("delta_gamma")
    problem_data["delta_beta"] = path_info.get("delta_beta")
    if problem_data["delta_gamma"] is None:
        problem_data["delta_gamma"] = self.query_gamma.input()
    if problem_data["delta_beta"] is None:
        problem_data["delta_beta"] = self.query_beta.input()

    path_info["delta_gamma"] = problem_data["delta_gamma"]
    path_info["delta_beta"] = problem_data["delta_beta"]

    return dict()

recommend_algorithm

recommend_algorithm(problem_data)

recommends an algorithm based on the problem_data and configuration

currently recommends QAOA for MaxCut and VQE for TSP

Source code in src/quast_decisiontree/nodes/algorithm_select.py
46
47
48
49
50
51
52
53
54
55
56
def recommend_algorithm(problem_data: dict) -> str:
    """recommends an algorithm based on the problem_data and configuration

    currently recommends QAOA for MaxCut and VQE for TSP
    """
    if problem_data.get("problem_class") == "MaxCut":
        return "QrispQAOA"
    elif problem_data.get("problem_class") == "TSP":
        return "QrispVQE"
    else:
        return "QrispVQE"