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

writeBestSol do not save on file #936

Closed
adover134 opened this issue Dec 10, 2024 · 10 comments
Closed

writeBestSol do not save on file #936

adover134 opened this issue Dec 10, 2024 · 10 comments

Comments

@adover134
Copy link

adover134 commented Dec 10, 2024

Describe the bug
I used this code.
m.writeBestSol(filename="block_e_i_piperack.mps")

I optimized the model after using redirectOutput().

The result was written on redirected page; for me, it was Jupyter Notebook output.
The file was blank.

To Reproduce
Optimize the model with redirectOutput() then try writeBestSol.

Expected behavior
The solution should be wrote on the file with filename.

Screenshots
This is the output from Jupyter with very simple example.
image

As you can see, it was saved on the output, not on the file which expected.

System

  • OS: Ubuntu
  • Version 24 lts
  • SCIP version: 10.0.0
  • How did you install pyscipopt? Using Git repo
@Joao-Dionisio
Copy link
Collaborator

Hello @adover134! I cannot reproduce this issue. When did you compile pyscipopt from the repo? Because we fixed redirectOutput last week in #929.

image
image

Also, why do you put a string as the objective of the problem? It seems a bit strange :)

@adover134
Copy link
Author

@Joao-Dionisio, I did not recognize that you've already solve it.
I did not installed the recent repo yet, maybe this was the problem.
But, for double check, have you opened the saved solution? You need to check whether anything is written in it.
And the objective, it was just a mistake.
Thank you for reply.

@Joao-Dionisio
Copy link
Collaborator

Yes, I checked the solution file and it contained the solution. Let me know if with the most recent changes your problem is fixed!

@adover134
Copy link
Author

Sure, but my current problem will take more than two days to solve... I will try as soon as the optimization is done.

@Jordan-Sun
Copy link

Hi there, I encountered the same issue, where the solution is saved to the redirected stdout file, rather then the solution output file I passed as a parameter.
The code that is causing the problem:

with contextlib.redirect_stdout(f):
    # Ask MIQCP to redirect output to python and let us redirect it
    assignment = dynamic_constrained.MIQCP(
        workload, original_assignment, interval, 1, f"{root}/solutions/{interval}.txt", True, bias)

And the core of function boils down to:

# Create the solver model
solver = Model("MIQCP")
# Skipping problem set up here
# If redirect_output is True, redirect the output to python, and let the user handle it
if redirect_output:
    solver.redirectOutput()
# Cap memory usage to 80 GB
solver.setRealParam("limits/memory", 80000.0)
# If max_threads is 1, solve the model under sequential mode
if max_threads == 1:
    solver.optimize()
# Otherwise, solve the model under multi-threaded mode
else:
    # Cap max_threads to 64 if it exceeds due to SCIP limitations
    max_threads = min(max_threads, 64)
    # Enable multi-threading to use all available cores
    solver.setParam("parallel/maxnthreads", max_threads)
    # Solve the model under concurrent mode
    solver.solveConcurrent()

# Get the best solution
sol = solver.getBestSol()

# Print the solution to the output file if a path is provided
if solution_file is not None:
    solver.writeBestSol(solution_file)

The pyscipopt version I am using is, so it should be the latest version:

python -c "import pyscipopt; print(pyscipopt.__version__)"
5.2.1

@Jordan-Sun
Copy link

Here's one of the stdout file that has the best solution attached to its end. I do not think the best solution is part of the normal model output. I hope this helps.
2.txt

@Jordan-Sun
Copy link

I tried to dive a bit into the source code and found that redirectOutput creates and sets a message handler by calling:

PY_SCIP_CALL(SCIPmessagehdlrCreate(&myMessageHandler, False, NULL, False, relayMessage, relayMessage, relayMessage, NULL, NULL))
PY_SCIP_CALL(SCIPsetMessagehdlr(self._scip, myMessageHandler))

And writeBestSol calls in SCIP with PY_SCIP_CALL(SCIPprintBestSol(self._scip, cfile, write_zeros)).
Under the hood, SCIP calls SCIP_CALL( SCIPprintTransSol(scip, sol, file, printzeros) ); at line 2432 of scip_sol.c
This calls the message handler that we set before:

SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value:                 ");
SCIPprintReal(scip, file, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob), 20, 9);
SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n");

I couldn't find where myMessageHandler is defined, so I would assume it is myMessageHandler that ignored the file argument and printed directly to stdout regardless, which caused the problem.

@Joao-Dionisio
Copy link
Collaborator

Hello, @Jordan-Sun! Can you please check if your problem is reproducible with the current master branch? We fixed this (or at least we think we did) very recently, it's not in the latest PyPi version yet.

@adover134
Copy link
Author

Sorry for late reply, @Joao-Dionisio. I tried with latest scip and pyscipopt, and it was not reproduced.

@Joao-Dionisio
Copy link
Collaborator

The original problem was fixed, so I'm closing the issue. If you can still reproduce your problem with the master branch, feel free to open a new issue @Jordan-Sun!

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

3 participants