Initial version

pull/1/head
Alinson S. Xavier 6 years ago
commit 3ef1733334

73
.gitignore vendored

@ -0,0 +1,73 @@
*$py.class
*.cover
*.egg
*.egg-info/
*.log
*.manifest
*.mo
*.pot
*.py,cover
*.py[cod]
*.sage.py
*.so
*.spec
.Python
.cache
.coverage
.coverage.*
.dmypy.json
.eggs/
.env
.hypothesis/
.installed.cfg
.ipynb_checkpoints
.mypy_cache/
.nox/
.pyre/
.pytest_cache/
.python-version
.ropeproject
.scrapy
.spyderproject
.spyproject
.tox/
.venv
.webassets-cache
/site
ENV/
MANIFEST
__pycache__/
__pypackages__/
build/
celerybeat-schedule
celerybeat.pid
coverage.xml
db.sqlite3
db.sqlite3-journal
develop-eggs/
dist/
dmypy.json
docs/_build/
downloads/
eggs/
env.bak/
env/
htmlcov/
instance/
ipython_config.py
lib/
lib64/
local_settings.py
nosetests.xml
parts/
pip-delete-this-directory.txt
pip-log.txt
pip-wheel-metadata/
profile_default/
sdist/
share/python-wheels/
target/
var/
venv.bak/
venv/
wheels/

@ -0,0 +1,3 @@
# MIPLearn: A Machine-Learning Framework for Mixed-Integer Optimization
# Copyright (C) 2019-2020 Argonne National Laboratory. All rights reserved.
# Written by Alinson S. Xavier <axavier@anl.gov>

@ -0,0 +1,41 @@
# MIPLearn: A Machine-Learning Framework for Mixed-Integer Optimization
# Copyright (C) 2019-2020 Argonne National Laboratory. All rights reserved.
# Written by Alinson S. Xavier <axavier@anl.gov>
from abc import ABC, abstractmethod
class Parameters(ABC):
"""
Abstract class for holding the data that distinguishes one relevant instance of the problem
from another.
In the knapsack problem, for example, this class could hold the number of items, their weights
and costs, as well as the size of the knapsack. Objects implementing this class are able to
convert themselves into concrete optimization model, which can be solved by a MIPSolver, or
into 1-dimensional numpy arrays, which can be given to a machine learning model.
"""
@abstractmethod
def to_model(self):
"""
Convert the parameters into a concrete optimization model.
"""
pass
@abstractmethod
def to_array(self):
"""
Convert the parameters into a 1-dimensional array.
The array is used by the LearningEnhancedSolver to determine how similar two instances are.
After some normalization or embedding, it may also be used as input to the machine learning
models. It must be numerical.
There is not necessarily a one-to-one correspondence between parameters and arrays. The
array may encode only part of the data necessary to generate a concrete optimization model.
The entries may also be reductions on the original data. For example, in the knapsack
problem, an implementation may decide to encode only the average weights, the average prices
and the size of the knapsack. This technique may be used to guarantee that arrays
correponding to instances of different sizes have the same dimension.
"""
pass

@ -0,0 +1,25 @@
# MIPLearn: A Machine-Learning Framework for Mixed-Integer Optimization
# Copyright (C) 2019-2020 Argonne National Laboratory. All rights reserved.
# Written by Alinson S. Xavier <axavier@anl.gov>
import pyomo.environ as pe
class LearningSolver:
"""
LearningSolver is a Mixed-Integer Linear Programming (MIP) solver that uses information from
previous runs to accelerate the solution of new, unseen instances.
"""
def __init__(self):
self.parent_solver = pe.SolverFactory('cplex_persistent')
self.parent_solver.options["threads"] = 4
def solve(self, params):
"""
Solve the optimization problem represented by the given parameters.
The parameters and the obtained solution is recorded.
"""
model = params.to_model()
self.parent_solver.set_instance(model)
self.parent_solver.solve(tee=True)

@ -0,0 +1,51 @@
# MIPLearn: A Machine-Learning Framework for Mixed-Integer Optimization
# Copyright (C) 2019-2020 Argonne National Laboratory. All rights reserved.
# Written by Alinson S. Xavier <axavier@anl.gov>
from .solvers import LearningSolver
from .core import Parameters
import numpy as np
import pyomo.environ as pe
import networkx as nx
class MaxStableSetGenerator:
"""Class that generates random instances of the Maximum Stable Set (MSS) Problem."""
def __init__(self, n_vertices, density=0.1, seed=42):
self.graph = nx.generators.random_graphs.binomial_graph(n_vertices, density, seed)
self.base_weights = np.random.rand(self.graph.number_of_nodes()) * 10
def generate(self):
perturbation = np.random.rand(self.graph.number_of_nodes()) * 0.1
weights = self.base_weights + perturbation
return MaxStableSetParameters(self.graph, weights)
class MaxStableSetParameters(Parameters):
def __init__(self, graph, weights):
self.graph = graph
self.weights = weights
def to_model(self):
nodes = list(self.graph.nodes)
edges = list(self.graph.edges)
model = m = pe.ConcreteModel()
m.x = pe.Var(nodes, domain=pe.Binary)
m.OBJ = pe.Objective(rule=lambda m : sum(m.x[v] * self.weights[v] for v in nodes),
sense=pe.maximize)
m.edge_eqs = pe.ConstraintList()
for edge in edges:
m.edge_eqs.add(m.x[edge[0]] + m.x[edge[1]] <= 1)
return m
def to_array(self):
return self.weights
def test_stab():
generator = MaxStableSetGenerator(n_vertices=100)
for k in range(5):
params = generator.generate()
solver = LearningSolver()
solver.solve(params)

@ -0,0 +1,11 @@
from setuptools import setup
setup(
name='miplearn',
version='0.1',
description='A Machine-Learning Framework for Mixed-Integer Optimization',
author='Alinson S. Xavier',
author_email='axavier@anl.gov',
packages=['miplearn'],
install_requires=['pyomo'],
)
Loading…
Cancel
Save