Adjust knapsack challenge; introduce round option

pull/1/head
Alinson S. Xavier 6 years ago
parent 2692e6946a
commit c1ede58fbe

@ -93,6 +93,8 @@ If `fix_w=True` is provided, then $w_{ij}$ are kept the same in all generated in
If a probability distribution `w_jitter` is provided, then item weights will be set to $w_{ij} + \gamma_{ij}$ where $\gamma_{ij}$ is sampled from `w_jitter`. When combined with `fix_w=True`, this argument may be used to generate instances where the weight of each item is roughly the same, but not exactly identical, across all instances. The prices of the items and the capacities of the knapsacks will be calculated as above, but using these perturbed weights instead.
By default, all generated prices, weights and capacities are rounded to the nearest number. If `round=False` is provided, this rounding will be disabled.
!!! note "References"
* Freville, Arnaud, and Gérard Plateau. *An efficient preprocessing procedure for the multidimensional 01 knapsack problem.* Discrete applied mathematics 49.1-3 (1994): 189-212.
* Fréville, Arnaud. *The multidimensional 01 knapsack problem: An overview.* European Journal of Operational Research 155.1 (2004): 1-21.

@ -11,19 +11,32 @@ from scipy.stats.distributions import rv_frozen
class ChallengeA:
def __init__(self, seed=0):
"""
- 250 variables, 10 constraints, fixed weights
- w ~ U(100, 900), jitter ~ U(-100, 100)
- K = 500, u ~ U(0., 1.)
- alpha = 0.25
"""
def __init__(self,
seed=42,
n_training_instances=300,
n_test_instances=50):
np.random.seed(seed)
self.gen = MultiKnapsackGenerator(n=randint(low=50, high=51),
m=randint(low=3, high=4),
w=uniform(loc=0.0, scale=200.0),
K=uniform(loc=1.0, scale=0.0),
u=uniform(loc=1.0, scale=0.0),
self.gen = MultiKnapsackGenerator(n=randint(low=250, high=251),
m=randint(low=10, high=11),
w=uniform(loc=100.0, scale=900.0),
K=uniform(loc=500.0, scale=0.0),
u=uniform(loc=0.0, scale=1.0),
alpha=uniform(loc=0.25, scale=0.0),
fix_w=True,
w_jitter=uniform(loc=-10.0, scale=20.0),
w_jitter=uniform(loc=-100.0, scale=200.0),
)
self.training_instances = self.gen.generate(300)
self.test_instances = self.gen.generate(50)
np.random.seed(seed + 1)
self.training_instances = self.gen.generate(n_training_instances)
np.random.seed(seed + 2)
self.test_instances = self.gen.generate(n_test_instances)
class MultiKnapsackInstance(Instance):
@ -90,7 +103,7 @@ class MultiKnapsackGenerator:
alpha=uniform(loc=0.25, scale=0.0),
fix_w=False,
w_jitter=randint(low=0, high=1),
seed=None,
round=True,
):
"""Initialize the problem generator.
@ -143,6 +156,8 @@ class MultiKnapsackGenerator:
If true, weights are kept the same (minus the noise from w_jitter) in all instances
w_jitter: rv_continuous
Probability distribution for random noise added to the weights
round: boolean
If true, all prices, weights and capacities are rounded to the nearest integer
"""
assert isinstance(n, rv_frozen), "n should be a SciPy probability distribution"
assert isinstance(m, rv_frozen), "m should be a SciPy probability distribution"
@ -161,6 +176,7 @@ class MultiKnapsackGenerator:
self.u = u
self.alpha = alpha
self.w_jitter = w_jitter
self.round = round
if fix_w:
self.fix_n = self.n.rvs()
@ -187,6 +203,10 @@ class MultiKnapsackGenerator:
alpha = self.alpha.rvs(m)
p = np.array([w[:,j].sum() / m + K * u[j] for j in range(n)])
b = np.array([w[i,:].sum() * alpha[i] for i in range(m)])
if self.round:
p = p.round()
b = b.round()
w = w.round()
return MultiKnapsackInstance(p, b, w)
return [_sample() for _ in range(n_samples)]

Loading…
Cancel
Save