1

How can I use a nonlinear function like numpy.where in xpress solver in Python? Is it possible? If not, what other method to use?

Daniel Junglas
  • 5,830
  • 1
  • 5
  • 22
  • 1
    Welcome to Stack Overflow. [Please don't post screenshots of text](https://meta.stackoverflow.com/a/285557/354577). They can't be searched or copied, or even consumed by users of adaptive technologies like screen readers. Instead, paste the code as text directly into your question. If you select it and click the `{}` button or Ctrl+K the code block will be indented by four spaces, which will cause it to be rendered as code. – ChrisGPT was on strike Jun 18 '22 at 17:02
  • You can't mix numpy and xpress variables this way. Advice: Get a piece of paper and first write down the mathematical model using elementary operations. Only once you understand this, transcribe into python/xpress. – Erwin Kalvelagen Jun 18 '22 at 18:54
  • thanks for response, but i should to get the index of ones in two lists and compare it for example i have liste1 = [1 0 0 1 0] ans liste2=[0 1 1 0 0] , i will calculate the index such as index_liste1 = [0 3] and index_liste1 = [1 2]. and finally i want to get abs(as index_liste1-as index_liste2) wich equal to [1 1] – Gheouany Saad Jun 18 '22 at 19:36
  • This is not a mathematical model. Life is much easier if you first write down a mathematical model. Mathematical optimization is about mathematical models. – Erwin Kalvelagen Jun 18 '22 at 19:50

1 Answers1

0

In order to use non-linear functions with xpress you have to wrap them as user functions by means of xpress.user(). Your code should look something like this:

for i in range(n_var):
    func = lambda y: (np.mean(np.where(y[:,1]==1)[0]) - np.mean(np.where(appliances[:,i]==1)[0]))**2
    m.addConstraint(xp.user(func, x) <= 6)

Note that things will not work as written above, though.

  1. xpress.user does not accept numpy arrays or lists at the moment. So you need to do something like *x.reshape(c*n,1).tolist() as second argument to xpress.user.
  2. The function passed as argument to xpress.user will not receive the variable objects but the values for the variable objects that were passed as arguments to xpress.user and these will be in a flat list. So your function will probably take a variable number of arguments by means of *args.

The following may work: it is completely untested but I hope you get the idea:

for i in range(n_var):
    vars_for_i = x[:,1]
    func = lambda *y: (np.mean(np.where(np.array(y).reshape(1,len(y))==1)[0]) - np.mean(np.where(appliances[:,i]==1)[0]))**2
    m.addConstraint(xp.user(func, *vars_for_i) <= 6)

You can probably do better than creating a new array in the function every time the function gets invoked.

Daniel Junglas
  • 5,830
  • 1
  • 5
  • 22