-
Notifications
You must be signed in to change notification settings - Fork 384
Batch generation of optimization variables #981
Comments
It would be nice to include a variable name format, e.g., |
I'd be happy to take this! |
Nice, let us know if you want to discuss something or need some help! A good starting point would be here, to see how a single variable is added: https://github.com/Qiskit/qiskit-aqua/blob/e1dfe0ef13b589bff7496518bf23195a8cd93377/qiskit/optimization/problems/quadratic_program.py#L194 |
There are some options for batch declaration in docplex for reference,
|
@obarbier Unfortunately, I can't commit to a regular correspondence. It may be faster for you to continue independently. |
Not sure if this is enough work for multiple people to work on, you'd probably run into merge conflicts since you are working on the same code. @obarbier you could maybe tackle another optimization stack issue, e.g. #980 or #982 (this one will be a bit more involved). Or maybe from Terra: Qiskit/qiskit#4349, Qiskit/qiskit#4348 or any that are labeled as good first issue 🙂 |
@t-imamichi @Cryoris I'm realizing that this becomes easier when the |
To be crystal clear, I'm assuming that |
Why would it be easier if it would default to The reason for not adding a default name is that you cannot add two variables of the same name. Thus, calling |
It just makes for a more compact implementation, IMO. This is what I have:
where |
Nice idea with the formatter 👍 But maybe there's a few corner cases that are a bit problematic, e.g.
I think a signature where we can do
For this we could check if What do you think? |
I prefer a format with only one placeholder 'prefix_{}_suffix'. def _add_variable(self,
lowerbound: Union[float, int] = 0,
upperbound: Union[float, int] = INFINITY,
vartype: Variable.Type = Variable.Type.CONTINUOUS,
name: str = 'x{}',
count: Optional[int] = None) -> Variable:
varname = name.format(self.get_num_vars() if count is None else count)
if varname in self._variable_index:
raise QiskitOptimizationError("Variable name already exists: {}".format(name))
self.variables_index[varname] = len(self.variables)
variable = Variable(self, varname, lowerbound, upperbound, vartype)
self.variables.append(variable)
return variable |
Thanks for your patience. Working on this part-time. How do we like this instead?
|
@Cryoris ^ |
Thanks for the update! In general this looks good, could you open a pull request so we can see the entire code and comment on it? |
Sorry for the hiatus. I've resumed work on this. Will have a PR in the next day or so. |
Allowing arbitrary names (so long as there is <= 1 occurrence of '{}' in the name) means allowing names like '_{x == y + 1}'. This is an actual name that is passed to 'binary_var' from the method 'from_docplex' in the 'quadratic_program' tests. It confuses the formatter because '{x == y + 1}' is treated as a substitution, when of course it is not. The simplest solution would be to disallow names containing substrings that match '{x}', for any 'x', but it would cause this test to fail. The more elaborate solution would be to transform the preexisting occurrences of '{' and '}' that are not '{}' into '{{' and '}}', causing the 'format' function to ignore them. We could reverse the transformation after the format call and before the result is returned. Then the test would pass. I'm not sure what types of names we need to be able to accomodate. As the length of the names we need to accomodate becomes longer, the second option becomes much less efficient than the first. Please let me know. |
@Cryoris ^ |
1 similar comment
@Cryoris ^ |
@t-imamichi Any thoughts ^ |
@Cryoris @t-imamichi Guys any feedback to above? I guess I am wondering why if we create n variable names say One other simple idea might be to allow the name to be a So for example
And given continuous and integer vars are similar I am sure above could be changed to be usuable by any of the methods say by passing in the function to add the var.. eg
Maybe you want Variable or List{Variable] to be returned from above since binary_var etc return Variable. Also instead of Union[str, List[str]] one could let it be Optional[Union[str, List[str]] = None so by default it uses whatever the default name is for creating the vars - i.e x0, x1 etc., so you could simply create a number of them like this too. |
@woodsp-ibm For what it's worth to the IBMQ superheroes... The motivation for the formatter was to provide functionality similar to I like the idea of generalizing one Regarding the return type of the |
Fixes qiskit-community#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances.
Fixes qiskit-community#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances.
Fixes qiskit-community#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances.
Fixes qiskit-community#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances.
Fixes qiskit-community#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances.
Fixes qiskit-community#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances.
* Batch generation of optimization variables Fixes #981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances. * Parameterize `var_dict` over `keys: Union[int, Sequence]`. * Move formatter verification into `_add_variables`. * Add `var_list` method to `QuadraticProgram` API. * simplify and add unit test * Remove `check_list` from `test_var_dict`. * Remove `check_dict` from `test_var_list`. * Batch generation of optimization variables Fixes #981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances. * Parameterize `var_dict` over `keys: Union[int, Sequence]`. * Move formatter verification into `_add_variables`. * Add `var_list` method to `QuadraticProgram` API. * Move `assert_equal` out one scope. * Remove unused functions. * Fix formatting issues. * Change `formatter` to `key_format`. * Remove unused import. * Add space. Co-authored-by: Takashi Imamichi <imamichi@jp.ibm.com> Co-authored-by: Takashi Imamichi <31178928+t-imamichi@users.noreply.github.com> Co-authored-by: Manoel Marques <Manoel.Marques@ibm.com>
…qua#1262) * Batch generation of optimization variables Fixes qiskit-community/qiskit-aqua#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances. * Parameterize `var_dict` over `keys: Union[int, Sequence]`. * Move formatter verification into `_add_variables`. * Add `var_list` method to `QuadraticProgram` API. * simplify and add unit test * Remove `check_list` from `test_var_dict`. * Remove `check_dict` from `test_var_list`. * Batch generation of optimization variables Fixes qiskit-community/qiskit-aqua#981 "To create n new variables in a quadratic program we have to write 'for _ in range(n): quadratic_program.binary_var()'" Now we can write 'quadratic_program.binary_var_dict(n)' to receive a dictionary mapping 'n' new binary variable names to their instances. * Parameterize `var_dict` over `keys: Union[int, Sequence]`. * Move formatter verification into `_add_variables`. * Add `var_list` method to `QuadraticProgram` API. * Move `assert_equal` out one scope. * Remove unused functions. * Fix formatting issues. * Change `formatter` to `key_format`. * Remove unused import. * Add space. Co-authored-by: Takashi Imamichi <imamichi@jp.ibm.com> Co-authored-by: Takashi Imamichi <31178928+t-imamichi@users.noreply.github.com> Co-authored-by: Manoel Marques <Manoel.Marques@ibm.com>
What is the expected enhancement?
To create
n
new variables in a quadratic program we have to writeIt seems counter-intuitive to not have a method where we can generate
n
variables at once, e.g.quadratic_program.add_binary_vars(n)
orquadratic_program.binary_vars(n)
.Are there any oppositions to adding this?
The text was updated successfully, but these errors were encountered: