parent
f713a399a8
commit
7a01d9cbcf
@ -0,0 +1,48 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
from .component import Component
|
||||||
|
from ..extractors import *
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from copy import deepcopy
|
||||||
|
import numpy as np
|
||||||
|
from sklearn.pipeline import make_pipeline
|
||||||
|
from sklearn.linear_model import LogisticRegression
|
||||||
|
from sklearn.preprocessing import StandardScaler
|
||||||
|
from sklearn.model_selection import cross_val_score
|
||||||
|
from sklearn.metrics import roc_curve
|
||||||
|
from sklearn.neighbors import KNeighborsClassifier
|
||||||
|
from tqdm.auto import tqdm
|
||||||
|
import pyomo.environ as pe
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class LazyConstraintsComponent(Component):
|
||||||
|
"""
|
||||||
|
A component that predicts which lazy constraints to enforce.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.violations = set()
|
||||||
|
|
||||||
|
def before_solve(self, solver, instance, model):
|
||||||
|
logger.info("Enforcing %d lazy constraints" % len(self.violations))
|
||||||
|
for v in self.violations:
|
||||||
|
cut = instance.build_lazy_constraint(model, v)
|
||||||
|
solver.internal_solver.add_constraint(cut)
|
||||||
|
|
||||||
|
def after_solve(self, solver, instance, model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def fit(self, training_instances):
|
||||||
|
for instance in training_instances:
|
||||||
|
if not hasattr(instance, "found_violations"):
|
||||||
|
continue
|
||||||
|
for v in instance.found_violations:
|
||||||
|
self.violations.add(v)
|
||||||
|
|
||||||
|
def predict(self, instance, model=None):
|
||||||
|
return self.violations
|
@ -0,0 +1,68 @@
|
|||||||
|
# MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
from miplearn import LearningSolver
|
||||||
|
from miplearn.problems.tsp import TravelingSalesmanGenerator, TravelingSalesmanInstance
|
||||||
|
import numpy as np
|
||||||
|
from numpy.linalg import norm
|
||||||
|
from scipy.spatial.distance import pdist, squareform
|
||||||
|
from scipy.stats import uniform, randint
|
||||||
|
|
||||||
|
|
||||||
|
def test_generator():
|
||||||
|
instances = TravelingSalesmanGenerator(x=uniform(loc=0.0, scale=1000.0),
|
||||||
|
y=uniform(loc=0.0, scale=1000.0),
|
||||||
|
n=randint(low=100, high=101),
|
||||||
|
gamma=uniform(loc=0.95, scale=0.1),
|
||||||
|
fix_cities=True).generate(100)
|
||||||
|
assert len(instances) == 100
|
||||||
|
assert instances[0].n_cities == 100
|
||||||
|
assert norm(instances[0].distances - instances[0].distances.T) < 1e-6
|
||||||
|
d = [instance.distances[0,1] for instance in instances]
|
||||||
|
assert np.std(d) > 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_instance():
|
||||||
|
n_cities = 4
|
||||||
|
distances = np.array([
|
||||||
|
[0., 1., 2., 1.],
|
||||||
|
[1., 0., 1., 2.],
|
||||||
|
[2., 1., 0., 1.],
|
||||||
|
[1., 2., 1., 0.],
|
||||||
|
])
|
||||||
|
instance = TravelingSalesmanInstance(n_cities, distances)
|
||||||
|
solver = LearningSolver()
|
||||||
|
solver.solve(instance)
|
||||||
|
x = instance.solution["x"]
|
||||||
|
assert x[0,1] == 1.0
|
||||||
|
assert x[0,2] == 0.0
|
||||||
|
assert x[0,3] == 1.0
|
||||||
|
assert x[1,2] == 1.0
|
||||||
|
assert x[1,3] == 0.0
|
||||||
|
assert x[2,3] == 1.0
|
||||||
|
assert instance.lower_bound == 4.0
|
||||||
|
assert instance.upper_bound == 4.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_subtour():
|
||||||
|
n_cities = 6
|
||||||
|
cities = np.array([
|
||||||
|
[0., 0.],
|
||||||
|
[1., 0.],
|
||||||
|
[2., 0.],
|
||||||
|
[3., 0.],
|
||||||
|
[0., 1.],
|
||||||
|
[3., 1.],
|
||||||
|
])
|
||||||
|
distances = squareform(pdist(cities))
|
||||||
|
instance = TravelingSalesmanInstance(n_cities, distances)
|
||||||
|
solver = LearningSolver()
|
||||||
|
solver.solve(instance)
|
||||||
|
x = instance.solution["x"]
|
||||||
|
assert x[0,1] == 1.0
|
||||||
|
assert x[0,4] == 1.0
|
||||||
|
assert x[1,2] == 1.0
|
||||||
|
assert x[2,3] == 1.0
|
||||||
|
assert x[3,5] == 1.0
|
||||||
|
assert x[4,5] == 1.0
|
Loading…
Reference in new issue