Algorithm 基于多约束算法的最优值求解
我有以下向量(或C矩阵和V向量)和K1,K2,K3常数Algorithm 基于多约束算法的最优值求解,algorithm,linear-programming,Algorithm,Linear Programming,我有以下向量(或C矩阵和V向量)和K1,K2,K3常数 Constraints [c11 + c12 + c13 + ... + c1n] <= K1 [c21 + c22 + c23 + ... + c2n] <= K2 [c31 + c32 + c33 + ... + c3n] <= K3 ------------------------------------------------- Valu
Constraints [c11 + c12 + c13 + ... + c1n] <= K1
[c21 + c22 + c23 + ... + c2n] <= K2
[c31 + c32 + c33 + ... + c3n] <= K3
-------------------------------------------------
Values [ v1 + v2 + v3 + ... + vn] -> Max
我正在寻找一种优雅的算法(也可能是Java或C#实现),它根据输入提供输出。我们可以假设约束的数量始终为3,并且提供了C和V(以及K1、K2、K3)的所有值
另一个简单的例子是:您有一个房间(3D),因此您的约束是房间的宽度、高度和长度(K1、K2、K3),并且您有一个家具项目列表(n个项目)。所有家具项目都有自己的长度(c1i)、宽度(c2i)、高度(c3i)和价值(vi)。您希望在房间中放置最有价值的家具,这些家具适合房间尺寸。输出是一个只有0和1个值的n长x变量,如果Xi=1,第i个元素被选入房间,如果席席=0,则不能拾取在房间中的第i个元素。 < P>这是多维0-1背包问题,它是NP-难。 可以在
python
中找到解决方法的概述、一篇相对较新的研究论文和一个遗传算法实现
取自python实现(上面的链接pyeasyga
)的示例如下:
from pyeasyga import pyeasyga
# setup data
data = [(821, 0.8, 118), (1144, 1, 322), (634, 0.7, 166), (701, 0.9, 195),
(291, 0.9, 100), (1702, 0.8, 142), (1633, 0.7, 100), (1086, 0.6, 145),
(124, 0.6, 100), (718, 0.9, 208), (976, 0.6, 100), (1438, 0.7, 312),
(910, 1, 198), (148, 0.7, 171), (1636, 0.9, 117), (237, 0.6, 100),
(771, 0.9, 329), (604, 0.6, 391), (1078, 0.6, 100), (640, 0.8, 120),
(1510, 1, 188), (741, 0.6, 271), (1358, 0.9, 334), (1682, 0.7, 153),
(993, 0.7, 130), (99, 0.7, 100), (1068, 0.8, 154), (1669, 1, 289)]
ga = pyeasyga.GeneticAlgorithm(data) # initialise the GA with data
ga.population_size = 200 # increase population size to 200 (default value is 50)
# define a fitness function
def fitness(individual, data):
weight, volume, price = 0, 0, 0
for (selected, item) in zip(individual, data):
if selected:
weight += item[0]
volume += item[1]
price += item[2]
if weight > 12210 or volume > 12:
price = 0
return price
ga.fitness_function = fitness # set the GA's fitness function
ga.run() # run the GA
print ga.best_individual() # print the GA's best solution
数据的最后一个维度是价格,另外两个维度是重量和体积
您可以调整此示例,使其解决两个以上维度的问题
我希望这有帮助
编辑:遗传算法通常不能保证找到最优解。对于三个约束,它可能会找到很好的解决方案,但不能保证最优
更新:数学优化解决方案
另一个选择是使用开源的数学优化问题建模框架。该框架调用一个解算器,即一个专门设计用于解决优化问题的软件。简言之,框架的工作是将数学问题描述与解决问题时需要的形式联系起来,而解算器的工作是实际解决问题
您可以使用,例如,pip
(pip-install-pulp
)安装纸浆
下面是前面在纸浆中建模的示例,通过修改示例:
将纸浆作为plp导入
#让我们保持相同的数据
数据=[(821,0.8118),(1144,1322),(634,0.7166),(701,0.9195),
(291, 0.9, 100), (1702, 0.8, 142), (1633, 0.7, 100), (1086, 0.6, 145),
(124, 0.6, 100), (718, 0.9, 208), (976, 0.6, 100), (1438, 0.7, 312),
(910, 1, 198), (148, 0.7, 171), (1636, 0.9, 117), (237, 0.6, 100),
(771, 0.9, 329), (604, 0.6, 391), (1078, 0.6, 100), (640, 0.8, 120),
(1510, 1, 188), (741, 0.6, 271), (1358, 0.9, 334), (1682, 0.7, 153),
(993, 0.7, 130), (99, 0.7, 100), (1068, 0.8, 154), (1669, 1, 289)]
w_帽,v_帽=12210,12
rng_项目=X范围(长度(数据))
#重新构造字典中的数据
items=['item_{}'。rng_items中i的格式(i)]
权重={items[i]:rng_items中i的数据[i][0]
卷={items[i]:rng_items中i的数据[i][1]
价格={items[i]:rng_items中i的数据[i][2]
#制造问题,将其声明为最大化问题
问题\u name=“3D背包”
prob=plp.LpProblem(问题名称,plp.LpProblem)
#定义变量
plp_vars=plp.LpVariable.dicts(“”,items,0,1,plp.LpInteger)
#目标函数
prob+=plp.lpSum([price[i]*plp\u vars[i]表示plp\u vars中的i])
#约束条件
prob+=plp.lpSum([weight[i]*plp_vars[i]for i in plp_vars])这是多维0-1背包问题,是NP难问题
可以在python
中找到解决方法的概述、一篇相对较新的研究论文和一个遗传算法实现
取自python实现(上面的链接pyeasyga
)的示例如下:
from pyeasyga import pyeasyga
# setup data
data = [(821, 0.8, 118), (1144, 1, 322), (634, 0.7, 166), (701, 0.9, 195),
(291, 0.9, 100), (1702, 0.8, 142), (1633, 0.7, 100), (1086, 0.6, 145),
(124, 0.6, 100), (718, 0.9, 208), (976, 0.6, 100), (1438, 0.7, 312),
(910, 1, 198), (148, 0.7, 171), (1636, 0.9, 117), (237, 0.6, 100),
(771, 0.9, 329), (604, 0.6, 391), (1078, 0.6, 100), (640, 0.8, 120),
(1510, 1, 188), (741, 0.6, 271), (1358, 0.9, 334), (1682, 0.7, 153),
(993, 0.7, 130), (99, 0.7, 100), (1068, 0.8, 154), (1669, 1, 289)]
ga = pyeasyga.GeneticAlgorithm(data) # initialise the GA with data
ga.population_size = 200 # increase population size to 200 (default value is 50)
# define a fitness function
def fitness(individual, data):
weight, volume, price = 0, 0, 0
for (selected, item) in zip(individual, data):
if selected:
weight += item[0]
volume += item[1]
price += item[2]
if weight > 12210 or volume > 12:
price = 0
return price
ga.fitness_function = fitness # set the GA's fitness function
ga.run() # run the GA
print ga.best_individual() # print the GA's best solution
数据的最后一个维度是价格,另外两个维度是重量和体积
您可以调整此示例,使其解决两个以上维度的问题
我希望这有帮助
编辑:遗传算法通常不能保证找到最优解。对于三个约束,它可能会找到很好的解决方案,但不能保证最优
更新:数学优化解决方案
另一个选择是使用开源的数学优化问题建模框架。该框架调用一个解算器,即一个专门设计用于解决优化问题的软件。简言之,框架的工作是将数学问题描述与解决问题时需要的形式联系起来,而解算器的工作是实际解决问题
您可以使用,例如,pip
(pip-install-pulp
)安装纸浆
下面是前面在纸浆中建模的示例,通过修改示例:
将纸浆作为plp导入
#让我们保持相同的数据
数据=[(821,0.8118),(1144,1322),(634,0.7166),(701,0.9195),
(291, 0.9, 100), (1702, 0.8, 142), (1633, 0.7, 100), (1086, 0.6, 145),
(124, 0.6, 100), (718, 0.9, 208), (976, 0.6, 100), (1438, 0.7, 312),
(910, 1, 198), (148, 0.7, 171), (1636, 0.9, 117), (237, 0.6, 100),
(771, 0.9, 329), (604, 0.6, 391), (1078, 0.6, 100), (640, 0.8, 120),
(1510, 1, 188), (741, 0.6, 271), (1358, 0.9, 334), (1682, 0.7, 153),
(993, 0.7, 130), (99, 0.7, 100), (1068, 0.8, 154), (1669, 1, 289)]
w_帽,v_帽=12210,12
rng_项目=X范围(长度(数据))
#重新构造字典中的数据
items=['item_{}'。rng_items中i的格式(i)]
权重={items[i]:rng_items中i的数据[i][0]
卷={items[i]:rng_items中i的数据[i][1]
价格={items[i]:
X = [0, 1, 1]
from pyeasyga import pyeasyga
# setup data
data = [(821, 0.8, 118), (1144, 1, 322), (634, 0.7, 166), (701, 0.9, 195),
(291, 0.9, 100), (1702, 0.8, 142), (1633, 0.7, 100), (1086, 0.6, 145),
(124, 0.6, 100), (718, 0.9, 208), (976, 0.6, 100), (1438, 0.7, 312),
(910, 1, 198), (148, 0.7, 171), (1636, 0.9, 117), (237, 0.6, 100),
(771, 0.9, 329), (604, 0.6, 391), (1078, 0.6, 100), (640, 0.8, 120),
(1510, 1, 188), (741, 0.6, 271), (1358, 0.9, 334), (1682, 0.7, 153),
(993, 0.7, 130), (99, 0.7, 100), (1068, 0.8, 154), (1669, 1, 289)]
ga = pyeasyga.GeneticAlgorithm(data) # initialise the GA with data
ga.population_size = 200 # increase population size to 200 (default value is 50)
# define a fitness function
def fitness(individual, data):
weight, volume, price = 0, 0, 0
for (selected, item) in zip(individual, data):
if selected:
weight += item[0]
volume += item[1]
price += item[2]
if weight > 12210 or volume > 12:
price = 0
return price
ga.fitness_function = fitness # set the GA's fitness function
ga.run() # run the GA
print ga.best_individual() # print the GA's best solution
import pulp as plp
# Let's keep the same data
data = [(821, 0.8, 118), (1144, 1, 322), (634, 0.7, 166), (701, 0.9, 195),
(291, 0.9, 100), (1702, 0.8, 142), (1633, 0.7, 100), (1086, 0.6, 145),
(124, 0.6, 100), (718, 0.9, 208), (976, 0.6, 100), (1438, 0.7, 312),
(910, 1, 198), (148, 0.7, 171), (1636, 0.9, 117), (237, 0.6, 100),
(771, 0.9, 329), (604, 0.6, 391), (1078, 0.6, 100), (640, 0.8, 120),
(1510, 1, 188), (741, 0.6, 271), (1358, 0.9, 334), (1682, 0.7, 153),
(993, 0.7, 130), (99, 0.7, 100), (1068, 0.8, 154), (1669, 1, 289)]
w_cap, v_cap = 12210, 12
rng_items = xrange(len(data))
# Restructure the data in dictionaries
items = ['item_{}'.format(i) for i in rng_items]
weight = {items[i]: data[i][0] for i in rng_items}
volume = {items[i]: data[i][1] for i in rng_items}
price = {items[i]: data[i][2] for i in rng_items}
# Make the problem, declare it as a maximization problem
problem_name = "3D Knapsack"
prob = plp.LpProblem(problem_name, plp.LpMaximize)
# Define the variables
plp_vars = plp.LpVariable.dicts('', items, 0, 1, plp.LpInteger)
# Objective function
prob += plp.lpSum([price[i]*plp_vars[i] for i in plp_vars])
# Constraints
prob += plp.lpSum([weight[i]*plp_vars[i] for i in plp_vars]) <= w_cap
prob += plp.lpSum([volume[i]*plp_vars[i] for i in plp_vars]) <= v_cap
# Solution
prob.solve()
# If you want to save the problem formulation in a file
# prob.writeLP(problem_name + 'lp')
# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
print v.name, "=", v.varValue
# The optimised objective function value is printed to the screen
print "Total gain = ", plp.value(prob.objective)
var env = new GRBEnv();
var model = new GRBModel(env);
var vars = model.AddVars(v.Length, GRB.BINARY);
model.Update();
GRBLinExpr obj = 0.0;
obj.AddTerms(v, vars, 0, v.Length);
model.SetObjective(obj, GRB.MAXIMIZE);
for (int i = 0; i < 3; i++) {
GRBLinExpr expr = 0.0;
for (int j = 0; j < C[i].Length; j++)
expr.AddTerm(C[i][j], vars[j]);
model.AddConstr(expr, GRB.LESS_EQUAL, K[i], "");
}
model.Update();
model.Optimize();