回溯法——批处理调度问题

181 阅读1分钟
  • M:各作业在各机器上所需的处理时间
  • f1:机器1完成处理的时间
  • f2:机器2完成处理的时间
  • f:完成时间和
  • x:路径数组,记录最优解
  • bestx:最优解
  • bestf:最优值
void backtrack(int i)
{
    if (i > n)
    {
        // 更新最优解
        for (int j = 1; i <= n; i++)
            bestx[j] = x[j];

        // 更新最优值
        bestf = f;
    }
    else
    {
        for (int j = i; j <= n; j++)
        {
            // 下面的三行用来计算f,即计算如果把这个作业安排在这里,完成时间会是什么时候
            f1 += M[x[j]][1];
            // 判断这个作业在机器1上完成的时刻,和上一个作业在机器2上完成的时刻,哪一个更晚?
            // 在更晚的那一个时刻后面再放到机器2上执行,再加上M[x[j]][2],代表了这个作业在机器2上完成的时刻
                f2[i] = ((f2[i - 1] > f1) ? f2[i - 1] : f1) + M[x[j]][2];
            f += f2[i];

            // 根据判断f是否小于之前得到的最优解,来决定要不要安排这个任务(产生这个节点)
            if (f < bestf)
            {
                swap(x[i], x[j]);
                backtrack(i + 1);
                swap(x[i], x[j]);
            }
            f1 -= M[x[j]][1]; // 置反f1。 不用置反f2,因为在进入新的分支后他会根据置反后的f1值重新计算,即被覆盖掉
            f -= f2[i];       // 置反f
        }
    }
}