Z3py 优化程序的异常行为

Unusual behaviour of Z3py optimization program

我正在编写一个程序,从 TMX website 中抓取 option_chain 数据,并根据这些数据建议优化的备兑看涨期权投资组合。对于优化过程,我使用了许多用户在本网站上讨论的 z3py 库。优化过程通过最大化溢价并将投资组合增量设置为用户指定的金额来工作。

最初,我在计算投资组合增量时犯了一个错误,这使得一切工作都非常顺利,但在更正后我遇到了问题。投资组合增量是通过采用投资组合中非零头寸的加权平均增量来计算的。为此,我使用了以下设置:

eng = Optimize()
Weights = [Real(row.symbol) for row in df.itertuples()]
#to count non-zero positions
TotCount = Real("TotCount")
eng.add(TotCount == Sum([If(w > 0, 1, 0) for w in Weights]))
eng.add(TotCount == If(TotCount >= 0, TotCount, 1))
#to get portfolio delta
eng.add(TotDelta == (Sum([(w * row.delta) for w, row in zip(Weights, df.itertuples())]) / TotCount))
eng.add(TotDelta == delta)
res = eng.check()

奇怪的行为发生在我 运行 this 作为循环中具有不同 delta 值的函数时,第一个循环实际上进行了计算并给出了答案,但在那之后我的代码卡在了最后一行几个小时没有任何进展。我尝试了一些方法,例如完全重新格式化它,但似乎没有什么不同。我想知道是否有人知道这里发生了什么?

不幸的是,您的描述中没有太多内容可供任何人在不了解您的设置的更多细节的情况下继续进行。从您的文本中可以推断出,约束很难解决 delta 需要更长时间的那些值。如果没有看到程序的其余部分,就不可能对可能发生的其他事情发表意见。

看看您是否可以隔离它 运行 缓慢开启的 delta 的值,并且仅 运行 它单独用于那个实例,以查看是否有来自其他地方的交互。这当然不是解决方案,但它是一种入门方式。

不过,我注意到的一件事是你有这条线:

eng.add(TotCount == If(TotCount >= 0, TotCount, 1))

让我们看看这行在说什么:如果 TotCount >= 0,那么它说 TotCount == TotCount。即,它对其没有任何限制。否则,它说 TotCount == 1;即,如果 TotCount < 0,则 TotCount == 1。那么后一种说法显然是错误的。也就是说,如果其他约束强制 TotCount < 0,那么您的程序将是 unsat。这实质上意味着整行在功能上等同于:

eng.add(TotCount >= 0)

任何人都很难判断这是否是您的本意;但我怀疑也许不是;因为你刚刚写了上面的简单形式。或许您想按照 if TotCount < 0,然后 make it 1 的方式说更多的话。但是查看前一行(即 Sum 表达式),我们发现情况永远不会如此。所以,那里有些可疑。

希望对您有所帮助;请注意,您不能 以这种方式为编程语言中的“顺序赋值”建模。 (你需要做所谓的单一静态赋值,a.k.a。SSA,转换。)但话又说回来,在不知道你的确切意图的情况下,很难发表意见。