Flow / Job Shop到布尔值可满足性[多项式时间缩减]第2部分

时间:2015-04-15 13:41:31

标签: c algorithm optimization reduction sat

这是我的第一个问题(Flow Shop to Boolean satisfiability [Polynomial-time reduction])的连续性。

因为有些事情是错的,我没有成功地知道究竟在哪里。我再次请求StackOverFlow大师的帮助:)

总结我现在拥有的东西:

  • 我的输入文件看起来像这样:
3 2
1 1 1
1 1 1
     

谁代表:3个工作,2个商店(机器),以及每个工作(机器)上每个工作的持续时间。我想要找到这些问题,找到最佳的C_max值。

例如,它应该在输出中给出这个结果(抱歉paint.exe xD):

C_max of the example

因此,为了阅读这些文件,我创建了2个结构:资源和问题看起来像这样:

typedef struct _resource {

   unsigned int numShop;
   unsigned int numJob;
   unsigned int value;

} Resource;

typedef struct _problem {

   unsigned int nbShops;
   unsigned int nbJobs;
   Resource** resources;

} Problem;

阅读没问题,我的结构中的输入文件中包含所有信息。

我想将这个最优问题(找到最佳解决方案)转换为决策问题(这是一个可能的解决方案吗?)为此,我的目标是将JobShop / FlowShop问题转换为SAT问题。

  • 我的目标如下:我将C_max的值设置为固定,我创建了一个SAT问题,我将减少C_max,直到SAT解算器说问题没有解决方案。带解决方案的最后一个值将是最佳值。

感谢@Jens Schauder,我有一个解决方案的开始。我的布尔变量是这样的:s_1_2_3 with the meaning resource one gets used at machine 2 starting from time 3

因此,如果我有J个工作,M个商店,我将我的C_max设为值C,我肯定会有:J * M * C布尔变量。

问题:目前我的SAT问题是错误的。给出的解决方案不合适。

以下是我现在的限制:(V表示“OR”,另一个表示“和”)

  • C1

这意味着我可以在一家商店工作一段时间k

  • C2

这意味着商店j在一段时间内只能处理1份工作。

  • C3

这意味着如果作业的持续时间超过1,则必须是连续的。因此,如果一个变量为真,则在任务持续时间结束之后的另一个变量也必须为真。

我不确定我是否对问题的表述是正确的,或者/如果我忘记了约束。

目前,我还介意Job Shop(Flow Shop基本上与每个商店的工作顺序相同)

对于这个非常大的问题感到抱歉,但对于这类问题,最好让所有细节都知道它是什么。


修改

我将添加上面3个约束的源代码,也许内部有问题而且我看不到...

约束条件1:

/** the job i can be on only 1 shop for a time k */
unsigned int writeConstraintOne(Problem* problem, unsigned int timeMax, FILE* file, char forReal) {

unsigned int final = 0;
unsigned int max = getNbVariables(problem,timeMax);

for(unsigned int i = 0; i < problem->nbShops; i++) {

  for(unsigned int l = 0; l < problem->nbShops; l++) {

    for(unsigned int j = 0; j < problem->nbJobs; j++) {

     for(unsigned int t = 0; t < timeMax; t++) {

      if(i == l) continue;

      /** We get the S_i_j_t */
      unsigned int A = getIdOfVariable(problem,i,j,t,timeMax);

      /** We get the S_l_j_t */
      unsigned int B = getIdOfVariable(problem,l,j,t,timeMax);

      final++;

      /* This fonction will or count the number of clauses, 
       * or write them inside the file. */
      if(forReal == 1) {

          /* It represents -A => B */
          fprintf(file,"-%d -%d 0\n",A,B);
      }
       }
      }
    }
   }
   return final;
 }

约束条件2:

/** shop j can handle only 1 job for a time k. */
unsigned int writeConstraintTwo(Problem* problem, unsigned int timeMax, FILE* file, char forReal) {

unsigned int final = 0;
unsigned int max = getNbVariables(problem,timeMax);

for(unsigned int i = 0; i < problem->nbShops; i++) {

  for(unsigned int l = 0; l < problem->nbJobs; l++) {

    for(unsigned int j = 0; j < problem->nbJobs; j++) {

     for(unsigned int t = 0; t < timeMax; t++) {

      if(j == l) continue;

      /** We get the S_i_j_t */
      unsigned int A = getIdOfVariable(problem,i,j,t,timeMax);

      /** We get the S_i_l_t */
      unsigned int B = getIdOfVariable(problem,i,l,t,timeMax);

      final++;

      /* This fonction will or count the number of clauses, 
       * or write them inside the file. */
      if(forReal == 1) {

          /* It represents -A => B */
          fprintf(file,"-%d -%d 0\n",A,B);
      }
       }
      }
    }
   }
   return final;
 }

约束条件3:

/** if the job has a duration more than 1, it has to be contineous. 
 *  So if one variable is true, the other after until the end of duration 
 *  of the task have to be true also. */
unsigned int writeConstraintThree(Problem* problem, unsigned int timeMax, FILE* file, char forReal) {

unsigned int final = 0;
unsigned int max = getNbVariables(problem,timeMax);

for(unsigned int i = 0; i < problem->nbShops; i++) {

    for(unsigned int j = 0; j < problem->nbJobs; j++) {

     for(unsigned int t = 0; t < timeMax; t++) {

     for(unsigned int k = 0; k < problem->resource[i][j].value-1; k++) {

      if(k == t) continue;

      /** We get the S_i_j_t */
      unsigned int A = getIdOfVariable(problem,i,j,t,timeMax);

      /** We get the S_i_j_k */
      unsigned int B = getIdOfVariable(problem,i,j,k,timeMax);

      final+= 2;

      /* This fonction will or count the number of clauses, 
       * or write them inside the file. */
      if(forReal == 1) {

          fprintf(file,"-%d %d 0\n",B,A);
          fprintf(file,"-%d %d 0\n",A,B);
      }
       }
      }
    }
   }
   return final;
 }

1 个答案:

答案 0 :(得分:1)

你给出的前两个等式中有一个错误:你错过了一个l!= j。当然我不知道你的代码中是否还有这个bug。

我认为你也缺少一个约束条件:每个工作必须至少在每台机器上进行一次(你最多只有一次)。

更多提示进行调试:尝试使用最简单的例子:1台机器,1个工作;并从那里工作到2台机器,1个工作和1个机器2个工作。

有2台机器和3个工作,可能会出现很多问题。