5

I'm using CPLEX python API to solve an optimization problem. The model is named DOT. When I run DOT.solve(), many information occur in the python console:

Iteration log ...
...
Network - Optimal:  Objective =    1.6997945303e+01
Network time = 0.48 sec. (91.93 ticks)  Iterations = 50424 (8674)
...

My question is that is there an easy way to get value of the elapsed time (i.e., 0.48 in my case)? And not just for the network optimizer, but for dual method, barrier method too.

I'm very new to python and CPLEX, and I'm very grateful for any help.

user12345
  • 117
  • 8

1 Answers1

2

To get the total solve time (in wall clock time), you can use the get_time method. To get the value for "Network time", as displayed in the log output, you'll have to parse the log output. Here's an example that demonstrates both of these:

from __future__ import print_function
import sys
import cplex


class OutputProcessor(object):
    """File-like object that processes CPLEX output."""

    def __init__(self):
        self.network_time = None

    def write(self, line):
        if line.find("Network time =") >= 0:
            tokens = line.split()
            try:
                # Expecting the time to be the fourth token. E.g.,
                # "Network", "time", "=", "0.48", "sec.", ...
                self.network_time = float(tokens[3])
            except ValueError:
                print("WARNING: Failed to parse network time!")
        print(line, end='')

    def flush(self):
        sys.stdout.flush()


def main():
    c = cplex.Cplex()
    outproc = OutputProcessor()
    # Intercept the results stream with our output processor.
    c.set_results_stream(outproc)
    # Read in a model file (required command line argument). This is
    # purely an example, thus no error handling.
    c.read(sys.argv[1])
    c.parameters.lpmethod.set(c.parameters.lpmethod.values.network)
    start_time = c.get_time()
    c.solve()
    end_time = c.get_time()
    print("Total solve time (sec.):", end_time - start_time)
    print("Network time (sec.):", outproc.network_time)


if __name__ == "__main__":
    main()

That should give you an idea of how to parse out other pieces of information from the log (it is not meant to be an example of a sophisticated parser).

You may be interested in get_dettime as well; it can be used the same way as get_time (as above), but is not susceptible to the load on your machine.

rkersh
  • 4,447
  • 2
  • 22
  • 31
  • I modified my code based on your answer, it worked, thanks! But I still have one more question: the total time seems to be much longer than network time (e.g. 1.72s versus 0.56s), why is that (what is it doing during "total time" period and during "network time" period?) – user12345 Oct 20 '17 at 05:21
  • 1
    The Python API is a wrapper around the Callable C Library. When you call `solve` in the Python API, there is extra code that determines which optimization routine to invoke (e.g., `CPXXmipopt`, `CPXXlpopt`, etc.), and when the optimization is finished it checks the status code to make sure an error didn't occur, etc. This extra processing is probably the difference you see. The "network time" is the time reported in the Callable C Library itself. The difference you are reporting is bigger than I have seen, but without knowing more about your model/program I can't really say anything else. – rkersh Oct 20 '17 at 15:47
  • Now I have a sketch idea. Thanks. – user12345 Oct 20 '17 at 16:52