Knapsack: change encoding; add simpler class for tests

pull/1/head
Alinson S. Xavier 6 years ago
parent e0b997b3fd
commit bb42815404

@ -19,7 +19,7 @@ class ChallengeA:
""" """
def __init__(self, def __init__(self,
seed=42, seed=42,
n_training_instances=300, n_training_instances=500,
n_test_instances=50): n_test_instances=50):
np.random.seed(seed) np.random.seed(seed)
@ -81,16 +81,18 @@ class MultiKnapsackInstance(Instance):
def get_instance_features(self): def get_instance_features(self):
return np.hstack([ return np.hstack([
self.prices, np.mean(self.prices),
self.capacities, self.capacities,
self.weights.ravel(),
]) ])
def get_variable_features(self, var, index): def get_variable_features(self, var, index):
return np.array([]) return np.hstack([
self.prices[index],
self.weights[:, index],
])
def get_variable_category(self, var, index): # def get_variable_category(self, var, index):
return index # return index
class MultiKnapsackGenerator: class MultiKnapsackGenerator:
@ -212,4 +214,34 @@ class MultiKnapsackGenerator:
return MultiKnapsackInstance(p, b, w) return MultiKnapsackInstance(p, b, w)
return [_sample() for _ in range(n_samples)] return [_sample() for _ in range(n_samples)]
class KnapsackInstance(Instance):
"""
Simpler (one-dimensional) Knapsack Problem, used for testing.
"""
def __init__(self, weights, prices, capacity):
self.weights = weights
self.prices = prices
self.capacity = capacity
def to_model(self):
model = pe.ConcreteModel()
items = range(len(self.weights))
model.x = pe.Var(items, domain=pe.Binary)
model.OBJ = pe.Objective(rule=lambda m: sum(m.x[v] * self.prices[v] for v in items),
sense=pe.maximize)
model.eq_capacity = pe.Constraint(rule=lambda m: sum(m.x[v] * self.weights[v]
for v in items) <= self.capacity)
return model
def get_instance_features(self):
return np.array([
self.capacity,
np.average(self.weights),
])
def get_variable_features(self, var, index):
return np.array([
self.weights[index],
self.prices[index],
])

@ -25,24 +25,6 @@ def test_knapsack_generator():
assert round(np.mean(b_sum), -3) == 25000. assert round(np.mean(b_sum), -3) == 25000.
def test_knapsack_instance():
instance = MultiKnapsackInstance(
prices=np.array([5.0, 10.0, 15.0]),
capacities=np.array([20.0, 30.0]),
weights=np.array([
[5.0, 5.0, 5.0],
[5.0, 10.0, 15.0],
])
)
assert (instance.get_instance_features() == np.array([
5.0, 10.0, 15.0, 20.0, 30.0, 5.0, 5.0, 5.0, 5.0, 10.0, 15.0
])).all()
solver = LearningSolver()
results = solver.solve(instance)
assert results["Problem"][0]["Lower bound"] == 30.0
def test_knapsack_fixed_weights_jitter(): def test_knapsack_fixed_weights_jitter():
gen = MultiKnapsackGenerator(n=randint(low=50, high=51), gen = MultiKnapsackGenerator(n=randint(low=50, high=51),
m=randint(low=10, high=11), m=randint(low=10, high=11),

Loading…
Cancel
Save