# Creating Decision Variables You must express the problem formulation in the program code to solve a combinatorial optimization problem with Amplify SDK. This page describes the first step in the formulation: generating the decision variables. {seealso} To issue decision variables, you can also use the {py:meth}~amplify.VariableGenerator.matrix method, as well as the methods described on this page, {py:meth}~amplify.VariableGenerator.scalar and {py:meth}~amplify.VariableGenerator.array of the {py:class}~amplify.VariableGenerator class. You can use the {py:meth}~amplify.VariableGenerator.matrix method to create a quadratic objective function in a coefficient matrix format. See "[Objective function with a coefficient matrix](matrix.md)" for details.  ## Creating a variable generator To formulate a combinatorial optimization problem, it is first necessary to create an instance of the {py:class}~amplify.VariableGenerator class. This class provides methods for issuing decision variables. {testcode} from amplify import VariableGenerator gen = VariableGenerator()  ## Variable generation You can use the {py:meth}~amplify.VariableGenerator.scalar method of the {py:class}~amplify.VariableGenerator class to issue a new decision variable by specifying the variable type. {list-table} :widths: auto :header-rows: 1 * - Variable type - Description * - {py:class}~amplify.VariableType.Binary - A variable taking the value 0 or 1 * - {py:class}~amplify.VariableType.Ising - A variable taking the value -1 or 1 * - {py:class}~amplify.VariableType.Integer - A variable taking an integer value * - {py:class}~amplify.VariableType.Real - A variable taking a real value  Following is an example of issuing a new binary variable. The variable is returned as an instance of the {py:class}~amplify.Poly class, which represents the polynomial of the variable. {doctest} >>> q = gen.scalar("Binary") >>> print(q) q_0  Issued variables are automatically named, but you can also specify a name. {doctest} >>> i = gen.scalar("Ising", name="i") >>> print(i) i  Integer or real variables can have a range of possible values. {doctest} >>> x = gen.scalar("Real", bounds=(2.0, 3.0)) >>> print(x) x_0  ## Creating an array of variables If you want to create multiple variables at once, you can use the {py:meth}~amplify.VariableGenerator.array method of the {py:class}~amplify.VariableGenerator class. This method returns an array of variables in a NumPy-like multidimensional array format. You can create an array of 3 binary variables as follows. Once the new variables are created, the variable names are automatically added with a string representing the array index. {doctest} >>> gen = VariableGenerator() >>> q = gen.array("Binary", 3) >>> print(q) [q_0, q_1, q_2]  You can retrieve the elements and slices like a Python {py:class}list or 1D NumPy array. {doctest} >>> print(q[0]) q_0  {doctest} >>> print(q[:2]) [q_0, q_1]  The {py:meth}~amplify.VariableGenerator.array method of the {py:class}~amplify.VariableGenerator class can also create multidimensional arrays. The following example creates a two-dimensional {math}2 \times 3 variable array. {doctest} >>> gen = VariableGenerator() >>> q = gen.array("Binary", shape=(2, 3)) >>> print(q) [[q_{0,0}, q_{0,1}, q_{0,2}], [q_{1,0}, q_{1,1}, q_{1,2}]]  You can retrieve elements and slices in the same way as for a two-dimensional {py:class}numpy.ndarray. The retrieved element or slice will be the view of the original array. {doctest} >>> print(q[0, 0]) q_{0,0}  {doctest} >>> print(q[0, :]) [q_{0,0}, q_{0,1}, q_{0,2}]  {doctest} >>> print(q[:, 0]) [q_{0,0}, q_{1,0}]  You can specify the lower and upper bounds for variables simultaneously at output time. {doctest} >>> n = gen.array("Integer", shape=(5,), bounds=(1, 3)) >>> print(n) [n_0, n_1, n_2, n_3, n_4]  {seealso} The {py:meth}~amplify.VariableGenerator.array method returns an instance of the {py:class}~amplify.PolyArray class, representing a polynomial array. The {py:class}~amplify.PolyArray class provides a variety of methods compatible with {py:class}~numpy.ndarray, as well as element retrieval and slicing. See the {py:class}~amplify.PolyArray class [reference](amplify.PolyArray) for details.  (variable-info)= ## Getting variable information To get variable information from a given variable, use the {py:meth}~amplify.Poly.as_variable method. {testcode} gen = VariableGenerator() q = gen.scalar("Binary") i = gen.scalar("Ising", name="i") x = gen.scalar("Real", bounds=(2.0, 3.0))  {doctest} >>> print(q.as_variable()) {name: q_0, id: 0, type: Binary}  The Amplify SDK provides variable information as an instance of the {py:class}~amplify.Variable class, which has the following attributes. {list-table} :width: 100% :header-rows: 1 * - Attribute - Data type - Details * - {py:attr}~amplify.Variable.name - {py:class}str - Variable name * - {py:attr}~amplify.Variable.id - {py:class}int - Variable ID number An integer value assigned starting from 0 in order of issuance * - {py:attr}~amplify.Variable.type - {py:class}~amplify.VariableType - Variable type * - {py:attr}~amplify.Variable.lower_bound - {py:class}float - [Integer or real variable only] Variable lower bound {py:obj}None means $- \inf$. * - {py:attr}~amplify.Variable.upper_bound - {py:class}float - [Integer or real variable only] Variable upper bound {py:obj}None means $+ \inf$.  In addition, information about variables issued by the {py:class}~amplify.VariableGenerator class can be obtained using the {py:attr}~amplify.VariableGenerator.variables property. {doctest} >>> vars = gen.variables >>> vars # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS [Variable({name: q_0, id: 0, type: Binary}), Variable({name: i, id: 1, type: Ising}), Variable({name: x_0, id: 2, type: Real, lower_bound: 2, upper_bound: 3})]  You can change the variable's name and lower and upper bounds later. {testcode} vars[2].name = "r" vars[2].lower_bound = 0.0 vars[2].upper_bound = 1.0  {doctest} >>> print(vars[2]) {name: r, id: 2, type: Real, lower_bound: 0, upper_bound: 1}  {attention} The variables returned by the methods such as the {py:meth}~amplify.VariableGenerator.scalar method are instances of the {py:class}~amplify.Poly class. Note that the {py:class}~amplify.Poly class can represent not only single variables but also general polynomials. However, the {py:meth}~amplify.Poly.as_variable method will only succeed if the {py:class}~amplify.Poly class instance represents a unary variable.  {tip} For convenience, when the {py:meth}~amplify.Poly.is_variable method returns {py:obj}True ({py:meth}~amplify.Poly.as_variable method succeeds), you can access the attributes of the {py:class}~amplify.Variable class directly. {doctest} >>> q.is_variable() True >>> q.name 'q_0' >>> q.id 0 >>> print(q.type) Binary   {tip} For each instance of the {py:class}~amplify.Poly class, you can retrieve information about all of the variables contained in that instance with the {py:attr}~amplify.Poly.variables property; see "[](objective.md)" for details about the {py:class}~amplify.Poly class. {doctest} >>> q.variables [Variable({name: q_0, id: 0, type: Binary})]