我想为Z3解算器添加一些变量的起始值,这些变量以前是通过一些启发式算法找到的。我希望能与他们更快地融合。我不想将它们添加为约束,我只是想提供一个初始起点,一个帮助就这么说。就像ILP的MIP开始一样。
这对Z3来说可能吗?如果是这样的话怎么样?我无法找到关于这个主题的任何内容。 (顺便说一句,我正在使用.NET API)
谢谢!
var myVar = ctx.MkIntConst("myVar");
// myVar.Start(5); or something like that
我想要应用开始的代码:
using (var ctx = new Context())
{
using (var slv = ctx.MkSolver())
//using (var slv = ctx.MkTactic("lia").Solver)
{
var srcArticlePos = new IntExpr[_articles.Count(), 3];
for (int i = 0; i < _articles.Count(); i++)
{
srcArticlePos[i, 0] = ctx.MkIntConst($"x[{i}]");
srcArticlePos[i, 1] = ctx.MkIntConst($"y[{i}]");
srcArticlePos[i, 2] = ctx.MkIntConst($"z[{i}]");
var a = _articles.ElementAt(i);
slv.Assert(srcArticlePos[i, 0] >= 0 & srcArticlePos[i, 0] < (int)(_box.Width - a.Width+1));
slv.Assert(srcArticlePos[i, 1] >= 0 & srcArticlePos[i, 1] < (int)(_box.Height - a.Height+1));
slv.Assert(srcArticlePos[i, 2] >= 0 & srcArticlePos[i, 2] < (int)(_box.Length - a.Length+1));
}
// Heuristic start
/*var lbp = new LAFFBinPacker();
var laffFits = lbp.FitsInABox(_articles, _box);
// get pack positions and clone
var pos = lbp.packedArticlePositions.ToDictionary(d => d.Key, d => d.Value.ToList());
// mip start
for (int i = 0; i < _articles.Count(); i++)
{
var a = _articles.ElementAt(i);
// take the first available position for this item and remove it from the list
if (pos.ContainsKey(a) && pos[a].Count > 0)
{
var p = pos[a][0];
pos[a].Remove(p);
var t = srcArticlePos[i, 0];
var test = srcArticlePos[i, 0].Args[0].;
srcArticlePos[i, 0].Args[0].
srcArticlePos[i, 0].Update(new Microsoft.Z3.IntExpr[] { new IntExpr(0) });
//varArticlePos[i, 0].Set(GRB.DoubleAttr.Start, p[1]);
//varArticlePos[i, 1].Set(GRB.DoubleAttr.Start, p[2]);
//varArticlePos[i, 2].Set(GRB.DoubleAttr.Start, p[0]);
}
}*/
for (int i = 0; i < _articles.Count(); i++)
{
var a1 = _articles.ElementAt(i);
var sX1 = srcArticlePos[i, 0];
var eX1 = srcArticlePos[i, 0] + (int)(a1.Width-1);
var sY1 = srcArticlePos[i, 1];
var eY1 = srcArticlePos[i, 1] + (int)(a1.Height-1);
var sZ1 = srcArticlePos[i, 2];
var eZ1 = srcArticlePos[i, 2] + (int)(a1.Length-1);
for (int j = i + 1; j < _articles.Count(); j++)
{
var a2 = _articles.ElementAt(j);
var sX2 = srcArticlePos[j, 0];
var eX2 = srcArticlePos[j, 0] + (int)(a2.Width-1);
var sY2 = srcArticlePos[j, 1];
var eY2 = srcArticlePos[j, 1] + (int)(a2.Height-1);
var sZ2 = srcArticlePos[j, 2];
var eZ2 = srcArticlePos[j, 2] + (int)(a2.Length-1);
slv.Assert(sX1 > eX2 | eX1 < sX2 | sY1 > eY2 | eY1 < sY2 | sZ1 > eZ2 | eZ1 < sZ2);
// no article with lower weight class must be above a higher one
if (a2.WeightClass > a1.WeightClass)
slv.Assert(sY1 < sY2);
else if (a2.WeightClass < a1.WeightClass)
slv.Assert(sY1 > sY2);
}
}
switch (slv.Check())
{
case Status.SATISFIABLE:
return true;
case Status.UNSATISFIABLE:
return false;
default:
throw new Exception();
}
}
}