Commit b642d584 authored by Bowen Wu's avatar Bowen Wu
Browse files

Improve parser, handle gurobi unbounded solution

parent 86c6aa3d
......@@ -67,6 +67,20 @@ class MPSProgram:
out += " {}\t\t{}\t\t{}\n".format(rhs_name, self.row_names[i], rhs_bounds[i])
out+="BOUNDS\n"
# TODO : output bounds
# we only care about the first bound name
bnd_lo = self.bnd[self.bnd_names[0]]['LO']
bnd_up = self.bnd[self.bnd_names[0]]['UP']
for col, lo, up in zip(self.col_names, bnd_lo, bnd_up):
if lo != 0:
if lo != -np.inf:
out += f" LO {self.bnd_names[0]}\t\t{col}\t\t{lo}\n"
else:
# we only allow FR to set lower bound to -inf
assert up == np.inf
out += f" FR {self.bnd_names[0]}\t\t{col}\n"
continue
if up != np.inf:
out += f" UP {self.bnd_names[0]}\t\t{col}\t\t{up}\n"
out+="ENDATA"
return out
......
import random
from mps_util import load_mps_dict, print_mps_dict
import pysmps.pysmps.smps_loader
from generator import MPSProgram
......@@ -12,20 +13,22 @@ class MutantMethod(object):
self.mut_cnt += 1
class ScaleMut(MutantMethod):
def __init__(self, scale) -> None:
def __init__(self, lo, hi) -> None:
super().__init__()
self.scale = scale
self.lo = lo
self.hi = hi
def __call__(self, mps):
mps["obj_coeff"] *= self.scale
mps["con_mat"] *= self.scale
scale = random.randrange(self.lo, self.hi)
mps["obj_coeff"] *= scale
mps["con_mat"] *= scale
for v in mps["rhs"].values():
v *= self.scale
v *= scale
for v in mps["bnd"].values():
for vv in v.values():
vv *= self.scale
vv *= scale
self.inc_cnt()
return mps
......@@ -76,7 +79,7 @@ class FlipSignMut(MutantMethod):
if __name__ == "__main__":
test_mps = "mps/testprob.mps"
sm = ScaleMut(scale = 0.5)
sm = ScaleMut(lo = -1, hi = 1)
smm = SparseMatMut(prob = 0.5)
dmm = DenseMatMut(prob = 0.9)
fsm = FlipSignMut(prob = 0.9)
......
......@@ -31,9 +31,10 @@ class bcolors:
UNDERLINE = '\033[4m'
def load_mps_dict(path):
name, objective_name, row_names, col_names, col_types, types, c, A, rhs_names, rhs, bnd_names, bnd = pysmps.pysmps.smps_loader.load_mps(path)
name, objsense, objective_name, row_names, col_names, col_types, types, c, A, rhs_names, rhs, bnd_names, bnd = pysmps.pysmps.smps_loader.load_mps(path)
ret = dict()
ret["name"] = name
ret["objsense"] = objsense
ret["obj_name"] = objective_name
ret["row_names"] = row_names
ret["col_names"] = col_names
......@@ -45,7 +46,6 @@ def load_mps_dict(path):
ret["rhs"] = rhs
ret["bnd_names"] = bnd_names
ret["bnd"] = bnd
ret["objsense"] = "MAX" # TODO: don't hardcode it
return ret
def print_mps_dict(mps: dict):
......@@ -53,8 +53,9 @@ def print_mps_dict(mps: dict):
print(f"{bcolors.OKBLUE}{k}\n{bcolors.ENDC}", mps[k])
def print_load_mps_ret(path):
name, objective_name, row_names, col_names, col_types, types, c, A, rhs_names, rhs, bnd_names, bnd = pysmps.pysmps.smps_loader.load_mps(path)
name, objsense, objective_name, row_names, col_names, col_types, types, c, A, rhs_names, rhs, bnd_names, bnd = pysmps.pysmps.smps_loader.load_mps(path)
print(f"{bcolors.OKBLUE}Program Name: {bcolors.ENDC}", name)
print(f"{bcolors.OKBLUE}Objective Sense: {bcolors.ENDC}", objsense)
print(f"{bcolors.OKBLUE}Objective Name: {bcolors.ENDC}", objective_name)
print(f"{bcolors.OKBLUE}Row Names: {bcolors.ENDC}", row_names)
print(f"{bcolors.OKBLUE}Column Names: {bcolors.ENDC}", col_names)
......
......@@ -136,6 +136,13 @@ class GurobiSolver(Solver):
model.setParam("DualReductions", 0)
model.optimize()
if self.get_sol_status(model) == UNBOUNDED:
# set the obj val to 0 and re-optimize
# in Gurobi, unbound does not imply feasible
with VerbosePrint(self.verbose):
model.setObjective(0, model.ModelSense)
model.optimize()
ret = dict()
ret["status"] = self.get_sol_status(model)
self.stats[ret["status"]] += 1
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment