You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am working on the column generation procedure to solve a scheduling problem. For that, as the sub-problem is a knapsack form, I would like to count all of the extreme points from the pricing and add those entirely to the master problem. I saw the related questions, but I am unsure whether the issue of taking the multiple optimal solutions is being fixed. What I am trying is:
However, I am trying to use the method mdl.writeSol(), but I am not aware of how to define the required argument solution to test and see what's really happened. I was wondering if, you could take a look and hint to me about that.
Installing collected packages: pyscipopt
Successfully installed pyscipopt-5.1.1
Install by PIP
Hey @abb-omidi! I think the issue is with the count method. Look at issue #838, it might be helpful to you.
In regards to column generation, I think using something like count will not be very helpful. You only want to get the negative reduced cost columns, and count will try to find every solution. Sure you can add a constraint to exclude the non-negative reduced cost ones, but even still, usually just keeping the ones found by SCIP when optimizing is enough. You want to get the updated duals for the next iteration, spending extra time finding suboptimal solutions does not seem the best approach.
Thanks for your comments. Also, the new online library is very useful.
I think the count method works well as it can truly gather feasible solutions. What I doubt works fine comes back to the writing function write allsolutions, which in SCIP writes the solution found in an external file. While it seems there is no such a method in the PySCIPOpt. The only defined method is writeSol which can display one of the gathering solutions in the best case. B.T.W I cannot find a way to write all of the solutions. However, having a nice function like count would be useful in many cases.
I tried to write an event handler to see what happened for BESTSOLFOUND as long as I called count instead of optimize, but it threw an error on the execution function:
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
[<ipython-input-8-1f83dbe54bc3>](https://localhost:8080/#) in <cell line: 77>()
76
77 if __name__ == "__main__":
---> 78 run_event()
[<ipython-input-8-1f83dbe54bc3>](https://localhost:8080/#) in run_event()
70 print(calls)
71 assert 'eventinit' in calls
---> 72 assert 'eventexec' in calls
73 assert 'eventexit' in calls
74 assert len(calls) == 3
AssertionError:
Regarding the column generation, in the first step, I have tried to generate the polyhedron from scratch to see the behavior of the master problem objective bounds Vs the objective of the compact formulation when the columns are added entirely at the beginning. In the second step, I would go with what you proposed. (That I will get back to you soon)
This is what @Opt-Mucca (who was also the one who made the new documentation, very useful indeed!) had to say about it:
If you enable countsols then SCIP is essentially hiding the solutions from itself. So it stores the solutions internally and gives you a valid count of solutions found, but SCIP itself does not have access to them (to do things like prune the search tree, etc, or terminate the search early).
I agree it would be nice if count worked the same way optimize does, I just don't know how big a change this would end up being.
--
As for your error in the callback, I think it might make sense, but it's difficult to be sure without the full code. From what I could understand of count, it basically throws away the objective function and it simply becomes a feasibility problem. Every time it finds a new solution, it adds a cut removing it, and reoptimizes. Without the objective function, maybe SCIP doesn't update BESTSOLFOUND. You're saying that the same callback works when using optimize instead of count?
It would be somewhat strange if SCIP could write the feasible solutions itself without throwing any issues, but PySCIPOpt cannot do that! It would be great if someone could take a closer look at the mapping functions between SCIP and PySCIPOpt to fix that.
An MRE to reproduce the error and the issue would be:
would you say please, how can we relax an integer problem without changing the variables type?
As I could find in the examples, there are some functions like relaxed or LP, but I am unsure if I understand how to use that in my case.
Also. in the reference you provided for B&P on the bin-packing problem, it seems it can be done by getTransformedCons, getDualfarkasLinear, and getDualsolLinear. I am wondering if, is there any simple example to use these methods to fully understand how they work.
P.S: @Joao-Dionisio, I could resolve some of my issues regarding relaxation and duals. Pls, let me check something, and I will get back to you asap.
Is it a necessery thing to define a pricer to capture the variables attributes to calculate the appropriate added columns or we can still use a loop to iterate over the extreme points/rays and update pricing problem and add column inside that?
Also. in the reference you provided for B&P on the bin-packing problem, it seems it can be done by getTransformedCons, getDualfarkasLinear, and getDualsolLinear. I am wondering if, is there any simple example to use these methods to fully understand how they work.
There is not, you can take a look at the documentation of the functions, which should explain them well enough.
Is it a necessery thing to define a pricer to capture the variables attributes to calculate the appropriate added columns or we can still use a loop to iterate over the extreme points/rays and update pricing problem and add column inside that?
There is nothing stopping you from using SCIP as an LP solver and do the column-generation process yourself, it's just extra work.
We will work on adding a function for getting the counted solutions. The issue is that they are stored in the constraint handler, not SCIPs traditional solution storage. We just need to write an appropriate function.
Dear @Opt-Mucca,
Thank you so much for your interest. Please, inform us when it is down. (🙏)
Dear @Joao-Dionisio,
Thanks for your answers and comments on how to run the code on GitHub. Also, I have tried to write the code I proposed in my last email in a modeling language. It works fine, but it cannot guarantee that it will reach optimality as it does not contain any tree search on the fly like the branching rule. (I actually implement price&branch). However, I need much time to adapt it to PySCIPOpt, specifically from the data structure point of view.
I am currently working on the BnP file you provided and I have some sort of questions. In order to implement branch&price and as far as I know,
1- we need to formulate an extended master problem.
2- defining the pricing model.
3- Initiating the master to ignite the process.
4- Looping over the master and pricing.
5- Checking if the master solution is integral, otherwise, branching.
Now, my questions are:
Would you confirm that my above intuition is correct?
Is there any reason to separate the pricer from the knapsack model?
I am not well familiar with Ryan-Foster, but would you confirm that adding the extra constraints in the pricer causes the knapsack polytope being unbounded? (I ask because in the code we obtain Farkas certificates!)
Does the function solve_knapsack() solve towards the optimization process? If so, what is the role of the function solve_knapsack_with_constraints? (AFAIK, the latter should be used?)
Is there a way to write the pricing problem as well as the master problem in each iteration? (I really would like to investigate the process step by step by hand and compare both results) Also, I think I have to set the node limit parameter to run iteratively.
1 - yes, your general understanding is correct.
2 - just to make the code tidier.
3 - I do not confirm that, a polytope cannot become unbounded by adding constraints. The Farkas certificates are mostly for the infeasibilities that might occur due to branching. They can also be useful for initializing column generation (see Farkas pricing)
4 - the knapsack without constraints is useful only for column generation at the root node, you are correct that the latter should be used.
5 - yes, you can use writeProblem() at the appropriate places.
The written problem of BnP in Github and the provided one before taking place co@work work the same? It seems the Github version in some classes has an entirely different data structure rather than the previous one, however as I checked in some instances the provided results of both are the same.
What actually the Farkas pricing works? (As I cannot find any appropriate documents.)
In the x[i] = m.addVar(vtype="B", name=f"x{i}", obj=values[i]) at knapsack class, how values[i] may take the dual value of the master constraints?
I have modified the code so that it can write the problems in each iteration of the algorithm. It seems that the master problem is only written at the first and the end of runtime. Is this normal behavior? I expected the master to be called many times in the solving process to update the duals and the rest of the needed parameters.
What is the difference between result[0] in the min_red_cost = 1 - result[0] and result[1] that be returned by function pricing_solver?
Is it possible to turn the heuristics off as long as the master and pricing problems are being solved?
I think there is a strange behavior in the running process of the BnP code. (Still In both versions as I said in my previous comment). The issue is that as long as the size of the items has exceeded bins capacity it can produce an infeasible solution as a feasible one. E.g. by the following simple data:
capacity = 5
sizes = [7,7,7]
the solver shows the following output while the compact model is running without any issues.
Would you say please, it is a bug or I am missing something?
(I think we need to add an event handler to check whether the subproblem is feasible or not. If not, return an infeasible flag and stop the process.).
They should work more or less the same, but the co@work repo is better tested, so you should stick to that one.
Section 4.1.2 of Marco Lubbecke's PhD thesis "Generic Branch-Cut-and-Price"
the price of the items in the knapsack subproblem is given by the duals of the master, you can take a look at marco's tutorial online
yes, this is normal behavior. SCIP is working more efficiently than just creating the master again and again at each iteration
1 - result[0] is the reduced cost. result[1] is the pattern, the actual solution, if I recall correctly.
You mean turning them off at the beginning? Yes, it is possible with model.setHeuristics(0), if my memory doesn't fail me.
That seems to be a bug, Abbas, thank you. Please don't open any more issues about co@work in this repo, do so in the co@work repo, please. I'll look later into what you talked about.
The counted solution issue first needs to be solved on the SCIP side. After looking into it, it just doesn't make sense to do on the Python side.
I worry this will get lost track of though.
Would you please take a look at this link? May I have missed something? Also, it would be great if the stored solution could be written the same as SCIP itself. (Pls, ignore the event handler)
Hello @abb-omidi. The new method is in PR #1270 , which hasn't been merged yet, and no release contains it.
Also, counting is only for integer variables, and presolving must be turned off.
Activity
Joao-Dionisio commentedon Sep 28, 2024
Hey @abb-omidi! I think the issue is with the
countmethod. Look at issue #838, it might be helpful to you.In regards to column generation, I think using something like count will not be very helpful. You only want to get the negative reduced cost columns, and count will try to find every solution. Sure you can add a constraint to exclude the non-negative reduced cost ones, but even still, usually just keeping the ones found by SCIP when optimizing is enough. You want to get the updated duals for the next iteration, spending extra time finding suboptimal solutions does not seem the best approach.
abb-omidi commentedon Sep 29, 2024
Dear @Joao-Dionisio,
Thanks for your comments. Also, the new online library is very useful.
I think the
countmethod works well as it can truly gather feasible solutions. What I doubt works fine comes back to the writing functionwrite allsolutions, which inSCIPwrites the solution found in an external file. While it seems there is no such a method in thePySCIPOpt. The only defined method iswriteSolwhich can display one of the gathering solutions in the best case. B.T.W I cannot find a way to write all of the solutions. However, having a nice function likecountwould be useful in many cases.I tried to write an event handler to see what happened for
BESTSOLFOUNDas long as I calledcountinstead ofoptimize, but it threw an error on the execution function:Regarding the column generation, in the first step, I have tried to generate the polyhedron from scratch to see the behavior of the master problem objective bounds Vs the objective of the compact formulation when the columns are added entirely at the beginning. In the second step, I would go with what you proposed. (That I will get back to you soon)
All the best
Joao-Dionisio commentedon Sep 29, 2024
This is what @Opt-Mucca (who was also the one who made the new documentation, very useful indeed!) had to say about it:
I agree it would be nice if
countworked the same wayoptimizedoes, I just don't know how big a change this would end up being.--
As for your error in the callback, I think it might make sense, but it's difficult to be sure without the full code. From what I could understand of
count, it basically throws away the objective function and it simply becomes a feasibility problem. Every time it finds a new solution, it adds a cut removing it, and reoptimizes. Without the objective function, maybe SCIP doesn't updateBESTSOLFOUND. You're saying that the same callback works when usingoptimizeinstead ofcount?abb-omidi commentedon Sep 29, 2024
It would be somewhat strange if
SCIPcould write the feasible solutions itself without throwing any issues, butPySCIPOptcannot do that! It would be great if someone could take a closer look at the mapping functions between SCIP and PySCIPOpt to fix that.An MRE to reproduce the error and the issue would be:
The result should be:
I was wondering if, you could take a look at this and see if it can be extended to write the rest of the solution.
Regards
abb-omidi commentedon Sep 29, 2024
Just as a follow-up question:
would you say please, how can we relax an integer problem without changing the variables type?
As I could find in the examples, there are some functions like
relaxedorLP, but I am unsure if I understand how to use that in my case.Also. in the reference you provided for
B&Pon the bin-packing problem, it seems it can be done bygetTransformedCons,getDualfarkasLinear, andgetDualsolLinear. I am wondering if, is there any simple example to use these methods to fully understand how they work.P.S: @Joao-Dionisio, I could resolve some of my issues regarding relaxation and duals. Pls, let me check something, and I will get back to you asap.
All the best
abb-omidi commentedon Oct 2, 2024
Dear support team,
Is it a necessery thing to define a pricer to capture the variables attributes to calculate the appropriate added columns or we can still use a loop to iterate over the extreme points/rays and update pricing problem and add column inside that?
Best
Joao-Dionisio commentedon Oct 4, 2024
there is the relax() method.
There is not, you can take a look at the documentation of the functions, which should explain them well enough.
There is nothing stopping you from using SCIP as an LP solver and do the column-generation process yourself, it's just extra work.
Opt-Mucca commentedon Oct 4, 2024
We will work on adding a function for getting the counted solutions. The issue is that they are stored in the constraint handler, not SCIPs traditional solution storage. We just need to write an appropriate function.
abb-omidi commentedon Oct 4, 2024
Dear @Opt-Mucca,
Thank you so much for your interest. Please, inform us when it is down. (🙏)
Dear @Joao-Dionisio,
Thanks for your answers and comments on how to run the code on GitHub. Also, I have tried to write the code I proposed in my last email in a modeling language. It works fine, but it cannot guarantee that it will reach optimality as it does not contain any tree search on the fly like the branching rule. (I actually implement price&branch). However, I need much time to adapt it to PySCIPOpt, specifically from the data structure point of view.
I am currently working on the
BnPfile you provided and I have some sort of questions. In order to implement branch&price and as far as I know,Now, my questions are:
solve_knapsack()solve towards the optimization process? If so, what is the role of the functionsolve_knapsack_with_constraints? (AFAIK, the latter should be used?)All the best
Joao-Dionisio commentedon Oct 5, 2024
Hey @abb-omidi .
1 - yes, your general understanding is correct.
2 - just to make the code tidier.
3 - I do not confirm that, a polytope cannot become unbounded by adding constraints. The Farkas certificates are mostly for the infeasibilities that might occur due to branching. They can also be useful for initializing column generation (see Farkas pricing)
4 - the knapsack without constraints is useful only for column generation at the root node, you are correct that the latter should be used.
5 - yes, you can use writeProblem() at the appropriate places.
abb-omidi commentedon Oct 10, 2024
Dear @Joao-Dionisio,
Would you confirm that:
BnPin Github and the provided one before taking placeco@workwork the same? It seems the Github version in some classes has an entirely different data structure rather than the previous one, however as I checked in some instances the provided results of both are the same.x[i] = m.addVar(vtype="B", name=f"x{i}", obj=values[i])at knapsack class, howvalues[i]may take the dual value of the master constraints?result[0]in themin_red_cost = 1 - result[0]andresult[1]that be returned by functionpricing_solver?All the best
abb-omidi commentedon Oct 12, 2024
Dear @Joao-Dionisio,
I think there is a strange behavior in the running process of the
BnPcode. (Still In both versions as I said in my previous comment). The issue is that as long as the size of the items has exceeded bins capacity it can produce an infeasible solution as a feasible one. E.g. by the following simple data:the solver shows the following output while the compact model is running without any issues.
I tried to write the
solve_knapsack_with_constraintsproblem and the result shows a somewhat irregular model.Would you say please, it is a bug or I am missing something?
(I think we need to add an
event handlerto check whether the subproblem is feasible or not. If not, return an infeasible flag and stop the process.).Best regards
Joao-Dionisio commentedon Oct 12, 2024
model.setHeuristics(0), if my memory doesn't fail me.That seems to be a bug, Abbas, thank you. Please don't open any more issues about co@work in this repo, do so in the co@work repo, please. I'll look later into what you talked about.
abb-omidi commentedon Oct 12, 2024
Dear @Joao-Dionisio,
Many thanks for your answers, specifically for the 4th bullet.
Just for clarification would you say you mean by
reduced[1]is actuallyresult[1]?Best regards
Joao-Dionisio commentedon Oct 28, 2024
Oh yeah, Abbas, you're right!
I'm closing the issue now, since the original question and the subsequent ones were answered.
EDIT: oh nevermind, the original problem was about getting counted solutions, sorry.
Opt-Mucca commentedon Dec 12, 2024
The counted solution issue first needs to be solved on the SCIP side. After looking into it, it just doesn't make sense to do on the Python side.
I worry this will get lost track of though.
abb-omidi commentedon Oct 24, 2026
Dear @Joao-Dionisio,
Would you please take a look at this link? May I have missed something? Also, it would be great if the stored solution could be written the same as SCIP itself. (Pls, ignore the event handler)
All the best
Joao-Dionisio commentedon Oct 24, 2026
Hello @abb-omidi. The new method is in PR #1270 , which hasn't been merged yet, and no release contains it.
Also, counting is only for integer variables, and presolving must be turned off.
abb-omidi commentedon Oct 27, 2026
@Joao-Dionisio,
Thanks for your informative comments
All the best