def assign_sections(tas, prioritize=False, analyze=False): """ tas: a list of ta objects i = index of sections j = index of tas The columns, x_i_j, go as follows: x_0_0, x_1_0, x_2_0, ..., x_0_1, ..., x_M_N """ M = len(tas[0].rankings) # number of section N = len(tas) # number of tas f = make_obj_f(tas, prioritize) A = make_coeff_m(M, N) b = make_b_v(tas, M, N) e = make_e_v(M, N) v = [1 for _ in range(M*N)] lp = lpm.lp_maker(f, A, b, e, None, v) # set branch and bound depth lps.lpsolve('set_bb_depthlimit', lp, 0) # set all variables to binary lps.lpsolve('set_binary', lp, v) # set lp to minimize the objective function lps.lpsolve('set_minim', lp) lps.lpsolve('write_lp', lp, LP_OUT) lps.lpsolve('solve', lp) res = lps.lpsolve('get_variables', lp)[0] lps.lpsolve('delete_lp', lp) parse_results(res, tas, M, analyze)
def assign_sections(students, prioritize=False, debug=False): """ students: a list of student objects i = index of sections j = index of students The columns, x_i_j, go as follows: x_0_0, x_1_0, x_2_0, ..., x_0_1, ..., x_M_N """ M = len(students[0].rankings) # number of section N = len(students) # number of students f = make_obj_f(students, prioritize) A = make_coeff_m(M, N) b = make_b_v(students, M, N) e = make_e_v(M, N) v = [1 for _ in range(M * N)] lp = lpm.lp_maker(f, A, b, e, None, v) # set branch and bound depth to be unlimited lps.lpsolve("set_bb_depthlimit", lp, 0) # set all variables to binary lps.lpsolve("set_binary", lp, v) # set lp to minimize the objective function lps.lpsolve("set_minim", lp) lps.lpsolve("write_lp", lp, LP_OUT) lps.lpsolve("solve", lp) res = lps.lpsolve("get_variables", lp)[0] lps.lpsolve("delete_lp", lp) parse_results(res, students, M, debug)
def get_lpsolve_handler(self, maxNameLength=255, startIndex=0): try: from lp_maker import lp_maker, lpsolve except ImportError: self.err('To export LP/MILP in files you should have lpsolve and its Python binding properly installed') self._Prepare() from ooMisc import LinConst2WholeRepr LinConst2WholeRepr(self) # set goal to min/max minim = 0 if self.goal in ['max', 'maximum'] else 1 # objective f = self._init_f_vector lp_handle = lp_maker(List(asarray(f).flatten()), List(self.Awhole), List(asarray(self.bwhole).flatten()), List(asarray(self.dwhole).flatten()), \ List(self.lb), List(self.ub), (1+asarray(self._intVars_vector)).tolist(), 0,minim) #lp_handle = lpsolve('make_lp', len(self.beq)+len(self.b), self.n) L = lambda action, *args: lpsolve(action, lp_handle, *args) # set name L('set_lp_name', self.name) # set boolean values if present #if len(self.boolVars)>0: #assert self.boolVars[0] in [True, False] #L('set_binary', self.boolVars) # set variables names if self.isFDmodel: assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers' #assert len(self.freeVars) == self.n, 'not implemented yet for oovars of size > 1' #names = [oov.name for oov in self.freeVars] x0 = self._x0 names = [] #assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers' for oov in self.freeVars: if oov.name.startswith('unnamed'): L('delete_lp') self.err('For exporting FuncDesigner models into MPS files you cannot have variables with names starting with "unnamed"') if ' ' in oov.name: L('delete_lp') self.err('For exporting FuncDesigner models into MPS files you cannot have variables with spaces in names') Size = asarray(x0[oov]).size if Size == 1: Name = oov.name names.append(Name) else: tmp = [(oov.name + ('_%d' % (startIndex+j))) for j in range(Size)] names += tmp Name = tmp[-1] if maxNameLength < len(Name): L('delete_lp') self.err('incorrect name "%s" - for exporting FuncDesigner models into MPS files you cannot have variables with names of length > maxNameLength=%d'% maxNameLength) # TODO: check are names unique L('set_col_name', names) return lp_handle
def assign_placements(): num_tas = len(all_tas) num_times = len(ID_TO_TIMES) upper = [1 for _ in range(num_tas * num_times)] # max value must be 1 obj_func = make_obj_func() constr_mat = make_constr_mat(num_tas, num_times) b_vector = make_b_vector() e_vector = make_e_vector(num_tas, num_times) lp = lpm.lp_maker(obj_func, constr_mat, b_vector, e_vector) lps.lpsolve('set_bb_depthlimit', lp, 0) # set branch and bound depth limit lps.lpsolve('set_binary', lp, upper) # all values must be either 0 or 1 lps.lpsolve('solve', lp) vars = lps.lpsolve('get_variables', lp)[0] lps.lpsolve('delete_lp', lp) output_results(vars)
def solve_linprog(c, A_ub, b_ub, A_eq, b_eq, bounds): """ solve a integer linear program either using scipy's Simplex algorithm or the external library lpsolve """ try: # use lpsolve from lp_maker import lp_maker, lpsolve # convert to format expected by lpsolve c = c.astype(int).tolist() # c.x is the linear objective function a = np.vstack((A_eq, A_ub)).astype(int).tolist( ) # matrix which contains both equality and inequality constraints, A_eq.x == b_eq, A_ub.x <= b_ub b = np.hstack((b_eq, b_ub)).astype(int).tolist( ) # right hand side of equality and inequality constraints e = np.hstack(([0 for bi in b_eq], [-1 for bi in b_ub])).tolist() nvars = len(b_eq) + len(b_ub) # number of integer variables xi xint = [i for i in range(1, nvars + 1)] vlb = [bound[0] for bound in bounds] vub = [bound[1] for bound in bounds] # build lpsolve object lp = lp_maker(c, a, b, e, vlb, vub, xint) lpsolve('solve', lp) lpsolve('get_objective', lp) X = lpsolve('get_variables', lp)[0] lpsolve('delete_lp', lp) return X except ImportError as e: # use scipy's linprog res = optimize.linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, bounds=bounds, options={ "maxiter": 10000000, "disp": True }) X = res.x print( "WARNING: simplex algorithm may not respect integer constraints! Some bond orders may not be integers." ) return X
def assign_placements(): """ Takes in an option for which to assign placements for. Outputs nothing, but calls output_results which prints all placements. """ num_tutors = len(all_tutors) num_times = len(ID_TO_TIMES) upper = [1 for _ in range(num_tutors * num_times)] # max value must be 1 obj_func = make_obj_func() constr_mat = make_constr_mat(num_tutors, num_times) b_vector = make_b_vector() e_vector = make_e_vector(num_tutors, num_times) lp = lpm.lp_maker(obj_func, constr_mat, b_vector, e_vector) lps.lpsolve('set_bb_depthlimit', lp, 0) # set branch and bound depth limit lps.lpsolve('set_binary', lp, upper) # all values must be either 0 or 1 lps.lpsolve('solve', lp) vars = lps.lpsolve('get_variables', lp)[0] lps.lpsolve('delete_lp', lp) output_results(vars)
def get_lpsolve_handler(self, maxNameLength=255, startIndex=0): try: from lp_maker import lp_maker, lpsolve except ImportError: self.err( 'To export LP/MILP in files you should have lpsolve and its Python binding properly installed' ) self._Prepare() from ooMisc import LinConst2WholeRepr LinConst2WholeRepr(self) # set goal to min/max minim = 0 if self.goal in ['max', 'maximum'] else 1 # objective f = self._init_f_vector lp_handle = lp_maker(List(asarray(f).flatten()), List(self.Awhole), List(asarray(self.bwhole).flatten()), List(asarray(self.dwhole).flatten()), \ List(self.lb), List(self.ub), (1+asarray(self._intVars_vector)).tolist(), 0,minim) #lp_handle = lpsolve('make_lp', len(self.beq)+len(self.b), self.n) L = lambda action, *args: lpsolve(action, lp_handle, *args) # set name L('set_lp_name', self.name) # set boolean values if present #if len(self.boolVars)>0: #assert self.boolVars[0] in [True, False] #L('set_binary', self.boolVars) # set variables names if self.isFDmodel: assert not isinstance( self.freeVars, set), 'error in openopt kernel, inform developers' #assert len(self.freeVars) == self.n, 'not implemented yet for oovars of size > 1' #names = [oov.name for oov in self.freeVars] x0 = self._x0 names = [] #assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers' for oov in self.freeVars: if oov.name.startswith('unnamed'): L('delete_lp') self.err( 'For exporting FuncDesigner models into MPS files you cannot have variables with names starting with "unnamed"' ) if ' ' in oov.name: L('delete_lp') self.err( 'For exporting FuncDesigner models into MPS files you cannot have variables with spaces in names' ) Size = asarray(x0[oov]).size if Size == 1: Name = oov.name names.append(Name) else: tmp = [(oov.name + ('_%d' % (startIndex + j))) for j in range(Size)] names += tmp Name = tmp[-1] if maxNameLength < len(Name): L('delete_lp') self.err( 'incorrect name "%s" - for exporting FuncDesigner models into MPS files you cannot have variables with names of length > maxNameLength=%d' % maxNameLength) # TODO: check are names unique L('set_col_name', names) return lp_handle