Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blackbox feature #65

Open
SHosseini94 opened this issue Mar 9, 2022 · 5 comments
Open

Blackbox feature #65

SHosseini94 opened this issue Mar 9, 2022 · 5 comments

Comments

@SHosseini94
Copy link

SHosseini94 commented Mar 9, 2022

Hi,

I am using the beta version of CP optimizer and its black-box class. I need to send a sequence variable to the black-box function and then return a dictionary containing some values.

I have read the example of stochastic-job-shop using black-box, but my model is a little bit different.

First, in my black-box function, I need to get the start of each interval in the sequence variable, but when I use method "get_start" while iterating in this sequence variable in the implemented black box function, it returns a tuple, which is (min_start, max_start) for that interval var.

Second, in my function, I get some values and I put them in a dictionary to use them later in CP model, but I cannot return a dictionary while using BlackBox. The dimension should be an integer of the number of returning values.

I appreciate you helping me in this regard.

Best,

@p-shaw
Copy link

p-shaw commented Mar 14, 2022

Hello,

I assume that you are using Python. You shouldn't need to use get_start though. That is an accessor on the modelling object and you want to have access to the current partial solution projected onto your black box variables. This happens automatically when you specify the arguments of your black box function. I've included an example below. I am not sure what you mean by wanting to return a dictionary. A black box expression needs to be something that can be incorporated into your CP Optimizer model, and CP Optimizer does not understand dictionaries. So, whatever value you return needs to be a numerical value or a vector of numerical values.

Regards.

from docplex.cp.model import CpoModel, CpoBlackboxFunction
import functools


def my_bb(seq, interval, interval_ids):
    sid = tuple(id(itv) for itv in seq)
    order = tuple(interval_ids.index(id(itv)) for itv in seq)
    # Do what you want with the order and intervals
    return max(i.end for i in interval)

N = 5

mdl = CpoModel()
task = [ mdl.interval_var(size = 1) for _ in range(N) ]
seq = mdl.sequence_var(task)
mdl.add(mdl.no_overlap(seq))
task_ids = tuple(id(t) for t in task)
bbf = CpoBlackboxFunction(functools.partial(my_bb, interval_ids = task_ids))
obj = bbf(seq, task)

mdl.add(mdl.minimize(obj))
mdl.add(obj >= N)

mdl.solve()

@SHosseini94
Copy link
Author

SHosseini94 commented Mar 14, 2022

Thanks so much for your clarification.

So, you mean it's possible only to return a vector when we have many values to return to the model? I was supposed to put these values in a dictionary format, making the results more interpretable.

In addition, Isn't the returned value a kind of integer expression? because while I use it in "element" command, it couldn't handle it, and it says you should put an integer expression as index.

Best

@p-shaw
Copy link

p-shaw commented Mar 16, 2022

Hello,

If you return a vector, that is not the value of an integer expression, but the value of multiple integer expressions. You then need to subscript to get the actual values. Like below.

Regards,

Paul

def my_bb(seq, interval, interval_ids):
   # Stuff ...
   return (val1, val2, val3) # Return 3 values!

# some things removed (see my previous post)

bbf = CpoBlackboxFunction(functools.partial(my_bb, interval_ids = task_ids), 3) # Specify three return values expected.
obj = bbf(seq, task)

# Subscript obj (0..2)
mdl.add(mdl.minimize(obj[0] + 2 * obj[1] + 4 * obj[2]))

@SHosseini94
Copy link
Author

Hello,

I did this way, but there is a problem. I am going to use the return value, an integer expression, in this command:

bbf = CpoBlackboxFunction(functools.partial(my_bb, interval_ids = task_ids), 3) # Specify three return values expected. obj = bbf(seq, task) **y=element(task,obj [0])**

But, I got this error:
AssertionError: At least one argument should be an integer expression representing index

I appreciate you guiding me on this.

Best,

@p-shaw
Copy link

p-shaw commented Mar 21, 2022

Hello,

You don't say it, but I imagine that you get an error creating the element expression. An element expression should take an array of integer expressions and an integer expression to index them. From what I understand task is an array of interval variables, so this cannot work.

Regards,

Paul

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants