我正在使用Python API来解决优化问题:找到大小为N(例如10)的二进制变量集以最大化它们的相互距离。为此,我整理了以下内容:
matrix = pd.read_csv("matrix.csv", index_col=0)
# declare integer variables
im = Model(name='max_weight_clique')
b = im.binary_var_dict(matrix.index.values)
# define objective function
clique_weight = im.sum(b[i] * b[j] * (matrix.loc[i, j] + matrix.loc[j, i])
for i, j in itertools.combinations(matrix.index, 2))
# add to key performance indicators
im.add_kpi(clique_weight, 'clique_weight')
# set size of clique
im.add_constraint(im.sum(b) == 10)
im.maximize(clique_weight)
我想将目标函数修改为最大化最小距离。当我尝试将此指定为以下内容时,我遇到了错误:
# minimum within clique
clique_min = im.min(adj_mat.loc[i, j] for i in adj_mat.index for j in adj_mat.index if b[i] == 1 and b[j] == 1)
im.add_kpi(clique_min, 'clique_min')
TypeError:无法将约束转换为布尔值:acc_num_NC_015394 == 1
我应该如何正确指定此约束?这似乎与此SO有关,但我的问题是python API特有的。
答案 0 :(得分:1)
您的公式中的问题是迭代器中涉及二元决策变量的'=='测试不会被识别为模型约束。
对这种约束进行建模的一个选择是使用指标约束。 以下是您的示例的可能配方:
bij_ind = im.binary_var_matrix(matrix.index.values, matrix.index.values, name='ind_')
clique_min = im.continuous_var(name='clique_min')
for i in matrix.index:
for j in matrix.index:
im.add(bij_ind[i, j] == im.min(b[i], b[j]))
im.add_indicator(bij_ind[i, j], clique_min <= adj_mat.loc[i, j])
im.add_kpi(clique_min, 'clique_min')
im.maximize(clique_min)
我不认为这种表述非常有效。