From 82a201e78b1d20250a6dfc715bff137031410e72 Mon Sep 17 00:00:00 2001 From: Evgeniy L Date: Tue, 2 Feb 2016 16:45:20 +0300 Subject: [PATCH] Add prototype of automatic allocation of raid like volumes The prototype shows how allocation algorithm can be implemented, using MIP (mixed integer programming), replication factor may be specified as a range, also user can specify size of each space on disk, all spaces for raids must be equal. --- lab_mip.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/lab_mip.py b/lab_mip.py index 32ff880..787d11a 100644 --- a/lab_mip.py +++ b/lab_mip.py @@ -18,6 +18,7 @@ import sys x = [] y = [] +z = [] thismodule = sys.modules[__name__] @@ -33,6 +34,12 @@ for i in range(6): setattr(thismodule, name, var) y.append(var) +for i in range(6 / 2): + name = 'z{0}'.format(i + 1) + var = LpVariable(name, 0, 1, 'Binary') + setattr(thismodule, name, var) + z.append(var) + # defines the problem prob = LpProblem("problem", LpMaximize) @@ -40,7 +47,6 @@ prob = LpProblem("problem", LpMaximize) # defines the objective function to maximize prob += x1 + x2 + x3 + x4 + x5 + x6, 'Sum of spaces' - # defines the constraints prob += x1 + x2 <= 100, 'First disk' prob += x3 + x4 <= 100, 'Second disk' @@ -48,10 +54,43 @@ prob += x5 + x6 <= 100, 'Third disk' prob += y1 + y3 + y5 == 2, 'Replication factor' -prob += x1 + x3 + x5 >= 20, 'First min size' -prob += x2 + x4 + x6 >= 101, 'Second min size' +prob += x2 + x4 + x6 >= 10, 'Second min size' -prob += x1 - x5 == 0, 'Sizes equality for raid' +# Specify min and max sizes for RAIDs using allocation size +# of each space, not sum of all spaces +prob += x1 >= y1 * 10 +prob += x1 <= y1 * 30 + +prob += x3 >= y3 * 10 +prob += x3 <= y3 * 30 + +prob += x5 >= y5 * 10 +prob += x5 <= y5 * 30 + +# z1, z2 and z3 are going to store info about available pairs +prob += z1 >= y1 + y3 - 1 +prob += z1 <= y1 +prob += z1 <= y3 + +prob += z2 >= y1 + y5 - 1 +prob += z2 <= y1 +prob += z2 <= y5 + +prob += z3 >= y3 + y5 - 1 +prob += z3 <= y3 +prob += z3 <= y5 + +# Make sizes equal if they are set +M = 10000000 + +prob += x1 - x3 + M * z1 <= M +prob += -x1 + x3 + M * z1 <= M + +prob += x1 - x5 + M * z2 <= M +prob += -x1 + x5 + M * z2 <= M + +prob += x3 - x5 + M * z3 <= M +prob += -x3 + x5 + M * z3 <= M # Convert from Float to Integer for i, x_ in enumerate(x): @@ -66,11 +105,16 @@ status = prob.solve(GLPK(msg=1)) def print_vector(vector, prefix, n=2): for i, v in enumerate(vector): - sys.stdout.write('{0}_{1} = {2}'.format(prefix, i + 1, value(v))) + sys.stdout.write('{0}{1} = {2}'.format(prefix, i + 1, value(v))) if (i + 1) % n: sys.stdout.write('\t') else: sys.stdout.write('\n') +print print_vector(x, 'x') +print print_vector(y, 'y') +print +print_vector(z, 'z', n=3) +print