unhashable type: 'BinaryQuadraticModel'
Hello everyone!
I was trying to solve QUBO problem via bqm and in defining objective function I wanted to add lambda (vector as regularization) as follows:
bqm = sum([lambdaic*(a_lic(i) - c_lic)*x[i] for i in range(r)]
however when I run it shows following error:
unhashable type: 'BinaryQuadraticModel' I will be happy if you give a hint to solve it!
Comments
Hello,
Are you able to post a bit more of your code?
It's a little difficult to tell which parts contain a BinaryQuadraticModel, and what the lambda function is doing.
Could you also please give a little more context as to how you are formulating or using the BQM?
Hello,here is my code:
lambdaic = np.random.rand(60)
def a_IC(i):
if i>= 0 and i <= 14:
return -2*sum([math.cos(m1(i)*np.pi*i1/X)*phi(i1) for i1 in X1])
if i>= 30 and i <= 44:
return -2*sum([math.sin(m1(i)*np.pi*i1/X)*phi(i1) for i1 in X1])
else:
return 0
x = [dimod.Binary(f'x_{i}') for i in range(60)]
bqm = sum([lambdaic*a_IC(i)*x[i] for i in range(60)])
sampler = LeapHybridSampler()
sampleset = sampler.sample(bqm)
and after running the code it shows that
TypeError: unhashable type: 'BinaryQuadraticModel'Hello,
Is the provided code exactly the same as the code you ran on your machine? I don't see the reference to the variable upper case X. I don't think that is the issue, but I see there are missing pieces of code.
Rather than providing all of the code, if you are able to reduce the code example to a minimal example that can be copied into an interpreter and run, reproducing the behaviour, it would very be helpful.
Please also provide the import statements you used.
I was able to run a reduced version of the above code:
So far I am not able to reproduce the issue locally using the provided code.
Are you able to run the following code?
This code gives me the same error that you are seeing.
The BinaryQuadraticModel instance is being used as the value for for a dictionary key.
The key is hashed in the process, which produces the error, due to the nature of the BinaryQuadraticModel class.
This might not be the same instance as what is happening in your code, however.
Please also provide the complete stack trace of the error, as it gives a trail back to the source of the error.
Hello!
Here is my complete code on my machine:
from dimod import BinaryQuadraticModel as BQM, quicksum
from dwave.system import LeapHybridSampler
from dimod import Binary, SampleSet
import dimod
import numpy as np
X = 5
X1 = list(range(0,X+1))
#creating random vector
lambdaic = np.random.rand(60)
def a_IC(i):
if i>= 0 and i <= 14:
return -2*sum([np.cos(i1/X) for i1 in X1])
if i>= 30 and i <= 44:
return -2*sum([np.sin(i1/X) for i1 in X1])
else:
return 0
x = [dimod.Binary(f'x_{i}') for i in range(60)]
bqm = sum([lambdaic*a_IC(i)*x[i] for i in range(60)])
from dwave.system.samplers import DWaveSampler
sampler = LeapHybridSampler()
sampleset = sampler.sample(bqm)
and the following error appears:
Hello,
It looks like you are creating a number of BQM instances in a list.
I can imagine that maybe the intention was to create one BQM instance?
If not then you would need to combine BQMs or call sample on each BQM.
In this case the BQMs are fairly small so I am guessing that they were meant to be all in one big BQM.
It sounds like you are able to formulate this problem as a QUBO.
What you will want to do is add the variables to the BQM after formulating the QUBO.
You can determine the variables' linear and quadratic terms and then add them to the BQM.
This link shows a very simple example with two linear terms and one quadratic term with named variables:
https://docs.ocean.dwavesys.com/en/stable/overview/formulation.html#example-bqm-for-a-boolean-circuit
Can you possibly describe what the following step should do? It might be an issue of notation that is producing a different problem formulation than expected.
bqm = sum([lambdaic*a_IC(i)*x[i] for i in range(60)])
The following screenshot shows what is produced by the above line:

Each row represents a different problem.
Running a for loop and sampling each one would produce a different solution set for each.
What was the output of BQM meant to look like? Can you show us a QUBO formulation of a simplified version?
Thanks for your patience and efforts.
Hello!
Thank you for your reply!
Yes my aim is to create one BQM instance.
I have formulated my problem as QUBO problem and it works.
However multiplying lambdaic to x[i] creates an issue for me. I would like to add lambdaic as Lagrange multiplier and check its effect.
Hello,
So it might be helpful to write out a 3x3 matrix and go through exactly what you are expecting to get back from each function to make sure you have the problem in the correct form.
This line for example is made up of several parts:
It would be helpful to check the output between each line and make sure that it is in the form you are expecting.
For example, what do the lines of the bqm represent?
Note that each line contains a value for the variables x_0, x_1, etc.
Should these values be added together?
Should these values actually have different variable names?
The output for [lambdaic*a_IC(i)*x[i] for i in range(60)] is:
Note again, it's made up of arrays of all the same variable. Is this what you were expecting?
Each one of these BinaryQuadraticModels is its own 1x1 QUBO with linear terms.
The output of the sum function combines these individual QUBOs into a larger one with linear terms for each variable name. But the output of the sum function is a list of QUBOs with a number of liner terms each.
You could sum twice and end up with one matrix, but it is not clear whether this is what you are aiming to do. It would very much depend on the problem.
The best way to tackle debugging this issue is by drawing a small 2x2 or 3x3 matrix, writing out all of the operations by hand, and then implementing each step and verifying the output.
If you can provide a simple example of how you would produce a small problem like this by hand, it will be easier to help assist with your understanding of the code libraries.
One way you could implement Lagrange parameters is by creating the different BQMs (BinaryQuadraticModel objects), multiplying them each by different values, and then combining them.
The combining step could vary between different models but there are a number of ways to do this, but you could use the BQM update method to combine multiple BQMs.
Another way is to do all of the desired operations in numpy, and then convert the matrix to a BQM format. You can try using the BQM from_numpy_vectors method.
It is worth looking at the available BQM methods.
Dear Johnson,
Thank you for your reply!
I will take into account all your comments and advices regarding solving this problem.
Best regards,
Aigerim
Please sign in to leave a comment.