This a simple script that I have been working on, which provides some Solver statistics to AMPL. At this moment, the script can handle the MINOS
solver output and generate cool charts to summarize the process till the solver reaches a solution.
As usual, I have written a python script that is called by the shell command in AMPL.
As usual, I have written a python script that is called by the shell command in AMPL.
option solver minos; option minos_options "Superbasics_limit=100 summary_file=1 1=summary.txt summary_level = 1 summary_frequency=1"; printf "MINOS_report: generating AMPL results...\n"; shell 'C:\Python27\python.exe "MINOS_report.py" summary.txt';As said, this script was written to work with MINOS, so after choosing MINOS as solver, we must provide to MINOS the output file which will contain the solver's statistics. The python script just parse the output file, clean it and generate the chart shown below. This code is just an example and does not aim to be very fast or optimum in terms of computational efficiency since is just a first test.
import pandas as pd import matplotlib.pyplot as plt import sys import os class Generate(object): def __init__(self, i_file): self.f_input = i_file self.f_output = "results_clean.csv" self.data = [] self.output = [] def clean_file(self): with open(self.f_input, "r") as f: it = 0 for line in f: if "EXIT" in line: break elif line[:7].strip().isdigit() and int(line[:7].strip()) > it \ and not "T" in line: if len(line) > 10: #print line it += 1 self.output.append(line) f.close() w = open(self.f_output, "w") w.writelines(self.output) w.close() print "MINOS_report: new file > {0}".format(self.f_output) def get_data(self): cols = [(1, 7), (8, 16), (17, 22), (23, 32), (33, 48), (49, 54), (55, 60), (61, 65)] self.data = pd.read_fwf(self.f_output, colspecs=cols, header=None) def plots(self): itn = len(self.data) rgradient = self.data[1] ninf = self.data[2] sinf = self.data[3] objective = self.data[4] nobj = self.data[5] ncon = self.data[6] nsb = self.data[7] it = list(range(1, itn + 1)) _min_obj = objective[itn - 1] _max_nsb = nsb[itn - 1] _max_nobj = nobj[itn - 1] _sinf = sinf[itn - 1] _ninf = ninf[itn - 1] _ncon = ncon[itn - 1] plt.figure("AMPL results") # plot 1 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ax1 = plt.subplot(211) ax1.set_title('Iterations={0}. Objective (optimal solution)={1}' .format(itn, _min_obj), size=10) ax1.set_xlabel('iterations') ax1.set_ylabel('objective function') l_obj = ax1.plot(it, objective, '.-', color="#0E3EEB", label="obj") ax2 = ax1.twinx() ax2.set_ylabel('reduced gradient') l_rg = ax2.plot(it, rgradient, '.-', color="#EB710E", label="rg") lns = l_obj + l_rg labs = [l.get_label() for l in lns] ax1.grid() ax1.legend(lns, labs, loc=0) # plot 2 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ax3 = plt.subplot(223) ax3.set_title('number of superbasics={0}\n # objective and gradient calculations={1}' .format(_max_nsb, _max_nobj), size=10) l_sb = ax3.plot(it, nsb, '.-', color="#0E3EEB", label="nsb") ax3.set_xlabel('iterations') ax3.set_ylabel('no.superbasics') ax4 = ax3.twinx() l_nobj = ax4.plot(it, nobj, '.-', color="#EB710E", label="nobj") ax4.set_ylabel('calculations obj. & gradient') lns = l_sb + l_nobj labs = [l.get_label() for l in lns] ax3.grid() ax3.legend(lns, labs, loc=4) # plot 3 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ plt.subplot(224) plt.title('no. of infeasibilities={0}\n sum of infeasibilities={1}\n ' '# nonlinear constraints evaluations={2}'.format(_ninf, _sinf, _ncon), size=10) plt.plot(it, ncon, 'g-', label="ncon") plt.plot(it, ninf, 'y-', label="ninf") plt.plot(it, sinf, 'm-', label="sinf") plt.xlabel('iterations') plt.grid() plt.legend() plt.tight_layout() plt.show() if __name__ == "__main__": summary_file = sys.argv[1] #summary_file = "C:/Users/Guillermo Navas/Desktop/MSc Statistics and Operations research/Continuous optimization/" \ # "Modelling and solving optimization problems/Lab assignment 2 _ Network flow problems/solver_summary.txt" report = Generate(summary_file) report.clean_file() report.get_data() report.plots()