我正在尝试使用用户图表上的二进制最小值来检测社区。为此,我试图使用Fiedler方法的变体,如this论文所示。这就是他们将其正式化的方式:
现在,我正在尝试使用matlab中的CVX包。这是我的代码:
tou = ((beta/ (e' * pi1 * e)) * tou1) + (((1 - beta) / (e' * pi2 * e)) * tou2);
n = 6;
cvx_begin
variable y(n)
minimize( y' * tou * y )
subject to
y' * pi1 * y == e' * pi1 * e
y' * pi2 * y == e' * pi2 * e
y' * pi1 * e == 0
y' * pi2 * e == 0
cvx_end
但它显示以下错误:
Disciplined convex programming error:
Invalid constraint: {convex} == {real constant}
Error in ==> cvx.eq at 12
b = newcnstr( evalin( 'caller', 'cvx_problem', '[]' ), x, y, '==' );
Error in ==> fiedler at 16
y' * pi1 * y == e' * pi1 * e
这里A1是一个定义如下的矩阵:
A1 = [0 3 2 0 0 0; 3 0 3 1 0 0; 2 3 0 0 0 0; 0 1 0 0 4 2; 0 0 0 4 0 3; 0 0 0 2 3 0];
同样A2 = A1。
pi1是矩阵是对角矩阵,其值等于该特定行中A1的所有值的总和。这样做我得到了
pi1 = [5 0 0 0 0 0; 0 7 0 0 0 0; 0 0 5 0 0 0; 0 0 0 7 0 0; 0 0 0 0 7 0; 0 0 0 0 0 5];
相似,pi1 = pi2。
并且tou1 = pi1-A1,并且tou2 = pi2-A2。
有人可以指出我到底做错了什么。这将是非常有帮助的。提前谢谢!
答案 0 :(得分:2)
这个问题就是你的约束
y'* pi1 * y == alpha
(其中alpha = e'*pi1*e
)不是凸约束。考虑二维情况,其中size(y)= [2 1]而pi1是身份,那么上面的约束是
y(1)^2 + y(2)^2 == alpha
这相当于要求y位于圆的半径上。这不是凸约束。
CVX专为纪律凸优化而设计。这意味着您必须以确保模型凸起的方式从基元构建模型。由于您的模型包含一个非凸的约束,CVX会发出错误:“Disciplined convex programming error”。
它还告诉你问题:“无效约束{凸} == {实常数}”。这告诉你,你试图将凸函数约束为等于常数。
如果要使用CVX解决此模型,则需要将模型重新表示为凸。如果你不能重新制定它,你可以尝试使用非线性(非复合)求解器。例如,MATLAB中包含的fmincon应该能够处理这种约束。请注意fmincon
是针对相当小规模的模型而设计的,对于大型非线性非coovex模型,您可能希望使用SNOPT或KNITRO等求解器。
答案 1 :(得分:0)
对于原始问题,通常可以通过用< =替换等号(=)来放宽等式约束。大多数情况下,解决方案将满足相等约束(但不能保证)。
原始问题可以放松如下:
tou = ((beta/ (e' * pi1 * e)) * tou1) + (((1 - beta) / (e' * pi2 * e)) * tou2);
n = 6;
cvx_begin
variable y(n)
minimize( y' * tou * y )
subject to
y' * pi1 * y <= e' * pi1 * e
y' * pi2 * y <= e' * pi2 * e
y' * pi1 * e <= 0
y' * pi2 * e <= 0
cvx_end
您需要验证解决方案(或选择其中一个解决方案)是否满足等式约束。 希望它适用于OP。