Search code examples
optaplanner

Benchmark Configuration - Error:PlanningProblem(null) can't be null


This question is a continuation of Implementing a SolutionIO Interface for Benchmarking.

In short, i'm working on a problem similar to the NurseRostering one from OptaPlanner. Currently i need to implement a benchmark, where i encountered the error from the link above.

Now that error has been resolved, and i'm getting the error The planningProblem (null) must not be null. Based on this i believe that my solution is not read properly and i need to make some adjustments. I did some research, did a lot of debugging, with not luck on finding what i need to do.

Below are all the configs,classes and interfaces that i have modified:

CustomBenchmarkIO:

public class CustomBenchmarkIO<Solution_> implements SolutionFileIO<Solution_>{

public String getInputFileExtension() {
    return null;
}

public String getOutputFileExtension() {
    return null;
}

public Solution_ read(File inputSolutionFile) {
    return null;
}

@Override
public void write(Solution_ solution, File outputSolutionFile) {

}

}

Note:<Solution_> is what i currently have, i tried both <Solution> and <Solution_> , both didn't work.

NurseRosterBenchmarkApp:

public static void main(String[] args) {
    new NurseRosteringBenchmarkApp().buildAndBenchmark(args);
}

public NurseRosteringBenchmarkApp() {
    super(
            new ArgOption("name",
                    "org/optaplanner/examples/nurserostering/benchmark/BenchmarkConfig.xml"));
}
Note: This is the default NurseRosterBenchmarkApp.

NurseRosterConsoleApp - I have my configured the NurseRosteringApp to run only from console.

public class NurseRosterConsoleApp extends CommonApp{
protected NurseRosterConsoleApp(String name, String description,    String solverConfig, String iconResource) {
    super(name, description, solverConfig, iconResource);
    // TODO Auto-generated constructor stub
}
// function for reading the solution from a file
public static Solution readSolution(File inputFile, boolean inputXmlType) {
    // reading from a solution xml file
    if (inputXmlType) {
        return (Solution) new NurseRosteringDao().readSolution(inputFile);
    } else {
        Solution solution;
        InputStream in = null;
        try {
            in = new FileInputStream(inputFile);
            SAXBuilder builder = new SAXBuilder(false);
            Document document = builder.build(in);
            XmlInputBuilder xmlInputBuilder = new NurseRosteringImporter.NurseRosteringInputBuilder();
            xmlInputBuilder.setInputFile(inputFile);
            xmlInputBuilder.setDocument(document);
            try {
                solution = (Solution) xmlInputBuilder.readSolution();
            } catch (IllegalArgumentException e) {
                throw new IllegalArgumentException("Exception in inputFile (" + inputFile + ")", e);
            } catch (IllegalStateException e) {
                throw new IllegalStateException("Exception in inputFile (" + inputFile + ")", e);
            }
        } catch (IOException e) {
            throw new IllegalArgumentException("Could not read the file (" + inputFile.getName() + ").", e);
        } catch (JDOMException e) {
            throw new IllegalArgumentException("Could not parse the XML file (" + inputFile.getName() + ").", e);
        } finally {
            IOUtils.closeQuietly(in);
        }
        return solution;
    }
}
public static void main(String[] args) {
    File inputXml = new File(Settings.inputFilePath);
    SolverFactory solverFactory = SolverFactory.createFromXmlResource(Settings.SOLVER_CONFIG);
    Solver solver = solverFactory.buildSolver();
    Solution unsolvedNurseRoster = readSolution(inputXml, Settings.inputXmlType);
    NurseRoster nurseRoster = (NurseRoster) unsolvedNurseRoster;
    solver.solve(unsolvedNurseRoster);
    NurseRoster solvedNurseRoster = (NurseRoster) solver.getBestSolution();
    try {
    } catch (Exception e) {
        e.printStackTrace();
    }
}
@Override
protected AbstractSolutionExporter createSolutionExporter() {
    return new NurseRosteringExporter();
}
@Override
protected SolutionDao createSolutionDao() {
    // TODO Auto-generated method stub
    return null;
}
@Override
protected SolutionPanel createSolutionPanel() {
    // TODO Auto-generated method stub
    return null;
}

}
Note: I extended the CommonApp class, and added all of the    unimplemented methods,
but it still didn't work. Also i configured the constructor to be the same as the OptaPlanner one 
(although i think it's for the GUI, correct me if i'm wrong).

BenchmarkConfig - It's the same as the previous question

<plannerBenchmark>
<benchmarkDirectory>local/data/nurserostering/location</benchmarkDirectory>
<warmUpSecondsSpentLimit>5</warmUpSecondsSpentLimit>
<inheritedSolverBenchmark>
    <problemBenchmarks>
        <solutionFileIOClass>org.optaplanner.examples.nurserostering.persistence.CustomBenchmarkIO</solutionFileIOClass>
        <inputSolutionFile>data/nurserostering/import/importTest/Input0.xml</inputSolutionFile>
    </problemBenchmarks>

My questions here are:

1. Am i missing something regarding configuring the solver?

2. Regarding the Exporter - Is it necessary to add all of my planning entities so that the solution will be created?

3. Will my NurseRosterConsoleApp cause problems with the benchmarking?

4. Where is the solution created?


Solution

  • Well i solved my problem. By now i thought that some methods read the Solution in the background, but since i debugged it a lot of times, i realized that i need to do that.

    The solution to the problem was simple:

    In the CustomBenchmarkIO class, in the Read method i just typed what i use to read the Solution in my other main( where i normally run it), and it worked.