为什么我会遇到 ILOG CP Optimizer 的段错误
Why am I getting a seg fault with ILOG CP Optimizer
我是约束编程的新手,我正在尝试使用 ILOG CP 优化器将我的第一个问题建模为约束程序。我已经安装了 ILOG Optimization Suite 20.1 并成功编译并 运行 许多包含的示例文件。
我想做的是在 2 个单元上安排 5 个任务。每个任务都有一个发布时间和一个截止时间。此外,在每个单元上,每个任务都有处理时间和处理成本。
以下是我的代码。
#include <ilcp/cp.h>
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
IloEnv env;
try
{
IloModel model(env);
IloInt numUnits = 2;
IloInt numTasks = 5;
IloIntervalVarArray dummyTasks(env, numTasks);
IloInt taskReleaseTimes[] = {0, 21, 15, 37, 3};
IloInt taskDueTimes[] = {200, 190, 172, 194, 161};
IloArray<IloBoolArray> unitTaskAssignment(env, numUnits);
unitTaskAssignment[0] = IloBoolArray(env, numTasks, IloTrue, IloTrue, IloFalse, IloTrue, IloTrue);
unitTaskAssignment[1] = IloBoolArray(env, numTasks, IloTrue, IloFalse, IloTrue, IloFalse, IloTrue);
IloArray<IloIntArray> unitTaskTimes(env, numUnits);
IloArray<IloNumArray> unitTaskCosts(env, numUnits);
IloIntArray minTaskTimes(env, numTasks);
IloIntArray maxTaskTimes(env, numTasks);
IloNumExpr totalCost(env);
unitTaskTimes[0] = IloIntArray(env, numTasks, 51, 67, 0, 24, 76);
unitTaskTimes[1] = IloIntArray(env, numTasks, 32, 0, 49, 0, 102);
unitTaskCosts[0] = IloNumArray(env, numTasks, 3.1, 3.7, 0.0, 3.4, 3.6);
unitTaskCosts[1] = IloNumArray(env, numTasks, 3.2, 0.0, 3.9, 0.0, 3.2);
IloArray<IloIntervalVarArray> taskUnits(env, numTasks);
IloArray<IloIntervalVarArray> unitTasks(env, numUnits);
for(IloInt i = 0; i < numTasks; i++)
{
IloInt minTaskTime = unitTaskTimes[0][i];
IloInt maxTaskTime = unitTaskTimes[0][i];
for(IloInt j = 1; j < numUnits; j++)
{
if(unitTaskTimes[j][i] < minTaskTime) minTaskTime = unitTaskTimes[j][i];
if(unitTaskTimes[j][i] > maxTaskTime) maxTaskTime = unitTaskTimes[j][i];
}
minTaskTimes[i] = minTaskTime;
maxTaskTimes[i] = maxTaskTime;
/* cout << "Minimum task time for task " << i << ": " << minTaskTimes[i] << endl;*/
/* cout << "Maximum task time for task " << i << ": " << maxTaskTimes[i] << endl;*/
}
char name[128];
for(IloInt i = 0; i < numTasks; i++)
{
taskUnits[i] = IloIntervalVarArray(env, numUnits);
sprintf(name, "dummyTask_%ld", i);
dummyTasks[i] = IloIntervalVar(env, minTaskTimes[i], maxTaskTimes[i]);
dummyTasks[i].setStartMin(taskReleaseTimes[i]);
dummyTasks[i].setEndMax(taskDueTimes[i]);
for(IloInt j = 0; j < numUnits; j++)
{
sprintf(name, "task%ld_in_unit%ld", j, i);
taskUnits[i][j] = IloIntervalVar(env, unitTaskTimes[j][i], name);
taskUnits[i][j].setOptional();
taskUnits[i][j].setStartMin(taskReleaseTimes[i]);
taskUnits[i][j].setEndMax(taskDueTimes[i]);
if(!unitTaskAssignment[j][i]) taskUnits[i][j].setAbsent();
totalCost += unitTaskCosts[j][i]*IloPresenceOf(env, taskUnits[i][j]);
}
model.add(IloAlternative(env, dummyTasks[i], taskUnits[i]));
}
for(IloInt j = 0; j < numUnits; j++)
{
unitTasks[j] = IloIntervalVarArray(env, numTasks);
for(IloInt i = 1; i < numTasks; i++)
{
unitTasks[j][i] = taskUnits[i][j];
}
model.add(IloNoOverlap(env, unitTasks[j]));
}
model.add(IloMinimize(env, totalCost));
IloCP cp(model);
cp.setParameter(IloCP::TimeLimit, 20);
if (cp.solve())
{
cout << "There's a solution." << endl;
}
else
{
cp.out() << "No solution found. " << std::endl;
}
}
catch (IloException & ex)
{
env.out() << "Caught " << ex << std::endl;
}
env.end();
return 0;
}
也许可以应用更好的逻辑,我很乐意就如何更好地建模问题提出建议,但这真的不是问题所在。
问题是,如果我注释掉这一行
model.add(IloNoOverlap(env, unitTasks[j]));
一切都可以编译并且 运行 很好,但是如果我保留它,程序会编译,但在执行时会出现段错误。为什么?
以下是 valgrind 输出,如果有帮助的话:
==361075== Memcheck, a memory error detector
==361075== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==361075== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==361075== Command: ./CP_test
==361075==
! --------------------------------------------------- CP Optimizer 20.1.0.0 --
! Minimization problem - 15 variables, 5 constraints
! TimeLimit = 20
! Initial process time : 1.00s (0.99s extraction + 0.02s propagation)
! . Log search space : 18.3 (before), 18.3 (after)
! . Memory usage : 335.4 kB (before), 335.4 kB (after)
! Using parallel search with 8 workers.
! ----------------------------------------------------------------------------
! Best Branches Non-fixed W Branch decision
0 15 -
+ New bound is 17.30000
^C==361075==
==361075== Process terminating with default action of signal 2 (SIGINT)
==361075== at 0x4882A9A: futex_wait (futex-internal.h:141)
==361075== by 0x4882A9A: futex_wait_simple (futex-internal.h:172)
==361075== by 0x4882A9A: pthread_barrier_wait (pthread_barrier_wait.c:184)
==361075== by 0xCEFA06: IlcParallel::SynchronizedMaster::workerSynchronize(IlcParallel::ThreadWorker*) (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0x66F224: IlcParallelEngineI::SynchronizedMaster::workerSynchronize(IlcParallel::ThreadWorker*) (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0xCF3B60: IlcParallel::SynchronizedMaster::ThreadIO::workerWaitInput() (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0xCF4182: IlcParallel::ThreadWorker::startup() (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0xCF5929: IlcThread::CallStartup(void*) (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0x487A608: start_thread (pthread_create.c:477)
==361075== by 0x4D0A292: clone (clone.S:95)
==361075==
==361075== HEAP SUMMARY:
==361075== in use at exit: 1,161,688 bytes in 353 blocks
==361075== total heap usage: 942 allocs, 589 frees, 2,260,411 bytes allocated
==361075==
==361075== LEAK SUMMARY:
==361075== definitely lost: 19,728 bytes in 1 blocks
==361075== indirectly lost: 9,752 bytes in 13 blocks
==361075== possibly lost: 2,304 bytes in 8 blocks
==361075== still reachable: 1,129,904 bytes in 331 blocks
==361075== of which reachable via heuristic:
==361075== stdstring : 35 bytes in 1 blocks
==361075== suppressed: 0 bytes in 0 blocks
==361075== Rerun with --leak-check=full to see details of leaked memory
==361075==
==361075== For lists of detected and suppressed errors, rerun with: -s
==361075== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
如有任何建议,我们将不胜感激。请注意,我曾尝试 post 访问 IBM 论坛,但由于某种原因显然我没有权限。
你有一个分段错误,因为 unitTasks[j][0] 是空指针,因为你的数组初始化循环从 1 开始。
此外,您应该尝试在调试模式下编译(没有 -DNDEBUG),因此当使用空句柄时您会遇到断言失败。
我是约束编程的新手,我正在尝试使用 ILOG CP 优化器将我的第一个问题建模为约束程序。我已经安装了 ILOG Optimization Suite 20.1 并成功编译并 运行 许多包含的示例文件。
我想做的是在 2 个单元上安排 5 个任务。每个任务都有一个发布时间和一个截止时间。此外,在每个单元上,每个任务都有处理时间和处理成本。
以下是我的代码。
#include <ilcp/cp.h>
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
IloEnv env;
try
{
IloModel model(env);
IloInt numUnits = 2;
IloInt numTasks = 5;
IloIntervalVarArray dummyTasks(env, numTasks);
IloInt taskReleaseTimes[] = {0, 21, 15, 37, 3};
IloInt taskDueTimes[] = {200, 190, 172, 194, 161};
IloArray<IloBoolArray> unitTaskAssignment(env, numUnits);
unitTaskAssignment[0] = IloBoolArray(env, numTasks, IloTrue, IloTrue, IloFalse, IloTrue, IloTrue);
unitTaskAssignment[1] = IloBoolArray(env, numTasks, IloTrue, IloFalse, IloTrue, IloFalse, IloTrue);
IloArray<IloIntArray> unitTaskTimes(env, numUnits);
IloArray<IloNumArray> unitTaskCosts(env, numUnits);
IloIntArray minTaskTimes(env, numTasks);
IloIntArray maxTaskTimes(env, numTasks);
IloNumExpr totalCost(env);
unitTaskTimes[0] = IloIntArray(env, numTasks, 51, 67, 0, 24, 76);
unitTaskTimes[1] = IloIntArray(env, numTasks, 32, 0, 49, 0, 102);
unitTaskCosts[0] = IloNumArray(env, numTasks, 3.1, 3.7, 0.0, 3.4, 3.6);
unitTaskCosts[1] = IloNumArray(env, numTasks, 3.2, 0.0, 3.9, 0.0, 3.2);
IloArray<IloIntervalVarArray> taskUnits(env, numTasks);
IloArray<IloIntervalVarArray> unitTasks(env, numUnits);
for(IloInt i = 0; i < numTasks; i++)
{
IloInt minTaskTime = unitTaskTimes[0][i];
IloInt maxTaskTime = unitTaskTimes[0][i];
for(IloInt j = 1; j < numUnits; j++)
{
if(unitTaskTimes[j][i] < minTaskTime) minTaskTime = unitTaskTimes[j][i];
if(unitTaskTimes[j][i] > maxTaskTime) maxTaskTime = unitTaskTimes[j][i];
}
minTaskTimes[i] = minTaskTime;
maxTaskTimes[i] = maxTaskTime;
/* cout << "Minimum task time for task " << i << ": " << minTaskTimes[i] << endl;*/
/* cout << "Maximum task time for task " << i << ": " << maxTaskTimes[i] << endl;*/
}
char name[128];
for(IloInt i = 0; i < numTasks; i++)
{
taskUnits[i] = IloIntervalVarArray(env, numUnits);
sprintf(name, "dummyTask_%ld", i);
dummyTasks[i] = IloIntervalVar(env, minTaskTimes[i], maxTaskTimes[i]);
dummyTasks[i].setStartMin(taskReleaseTimes[i]);
dummyTasks[i].setEndMax(taskDueTimes[i]);
for(IloInt j = 0; j < numUnits; j++)
{
sprintf(name, "task%ld_in_unit%ld", j, i);
taskUnits[i][j] = IloIntervalVar(env, unitTaskTimes[j][i], name);
taskUnits[i][j].setOptional();
taskUnits[i][j].setStartMin(taskReleaseTimes[i]);
taskUnits[i][j].setEndMax(taskDueTimes[i]);
if(!unitTaskAssignment[j][i]) taskUnits[i][j].setAbsent();
totalCost += unitTaskCosts[j][i]*IloPresenceOf(env, taskUnits[i][j]);
}
model.add(IloAlternative(env, dummyTasks[i], taskUnits[i]));
}
for(IloInt j = 0; j < numUnits; j++)
{
unitTasks[j] = IloIntervalVarArray(env, numTasks);
for(IloInt i = 1; i < numTasks; i++)
{
unitTasks[j][i] = taskUnits[i][j];
}
model.add(IloNoOverlap(env, unitTasks[j]));
}
model.add(IloMinimize(env, totalCost));
IloCP cp(model);
cp.setParameter(IloCP::TimeLimit, 20);
if (cp.solve())
{
cout << "There's a solution." << endl;
}
else
{
cp.out() << "No solution found. " << std::endl;
}
}
catch (IloException & ex)
{
env.out() << "Caught " << ex << std::endl;
}
env.end();
return 0;
}
也许可以应用更好的逻辑,我很乐意就如何更好地建模问题提出建议,但这真的不是问题所在。
问题是,如果我注释掉这一行
model.add(IloNoOverlap(env, unitTasks[j]));
一切都可以编译并且 运行 很好,但是如果我保留它,程序会编译,但在执行时会出现段错误。为什么?
以下是 valgrind 输出,如果有帮助的话:
==361075== Memcheck, a memory error detector
==361075== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==361075== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==361075== Command: ./CP_test
==361075==
! --------------------------------------------------- CP Optimizer 20.1.0.0 --
! Minimization problem - 15 variables, 5 constraints
! TimeLimit = 20
! Initial process time : 1.00s (0.99s extraction + 0.02s propagation)
! . Log search space : 18.3 (before), 18.3 (after)
! . Memory usage : 335.4 kB (before), 335.4 kB (after)
! Using parallel search with 8 workers.
! ----------------------------------------------------------------------------
! Best Branches Non-fixed W Branch decision
0 15 -
+ New bound is 17.30000
^C==361075==
==361075== Process terminating with default action of signal 2 (SIGINT)
==361075== at 0x4882A9A: futex_wait (futex-internal.h:141)
==361075== by 0x4882A9A: futex_wait_simple (futex-internal.h:172)
==361075== by 0x4882A9A: pthread_barrier_wait (pthread_barrier_wait.c:184)
==361075== by 0xCEFA06: IlcParallel::SynchronizedMaster::workerSynchronize(IlcParallel::ThreadWorker*) (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0x66F224: IlcParallelEngineI::SynchronizedMaster::workerSynchronize(IlcParallel::ThreadWorker*) (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0xCF3B60: IlcParallel::SynchronizedMaster::ThreadIO::workerWaitInput() (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0xCF4182: IlcParallel::ThreadWorker::startup() (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0xCF5929: IlcThread::CallStartup(void*) (in /home/nate/Dropbox/Princeton/Maravelias/DCA_Branch_and_Cut/cplex_implementation/CP_optimizer_test_instance/CP_test)
==361075== by 0x487A608: start_thread (pthread_create.c:477)
==361075== by 0x4D0A292: clone (clone.S:95)
==361075==
==361075== HEAP SUMMARY:
==361075== in use at exit: 1,161,688 bytes in 353 blocks
==361075== total heap usage: 942 allocs, 589 frees, 2,260,411 bytes allocated
==361075==
==361075== LEAK SUMMARY:
==361075== definitely lost: 19,728 bytes in 1 blocks
==361075== indirectly lost: 9,752 bytes in 13 blocks
==361075== possibly lost: 2,304 bytes in 8 blocks
==361075== still reachable: 1,129,904 bytes in 331 blocks
==361075== of which reachable via heuristic:
==361075== stdstring : 35 bytes in 1 blocks
==361075== suppressed: 0 bytes in 0 blocks
==361075== Rerun with --leak-check=full to see details of leaked memory
==361075==
==361075== For lists of detected and suppressed errors, rerun with: -s
==361075== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
如有任何建议,我们将不胜感激。请注意,我曾尝试 post 访问 IBM 论坛,但由于某种原因显然我没有权限。
你有一个分段错误,因为 unitTasks[j][0] 是空指针,因为你的数组初始化循环从 1 开始。 此外,您应该尝试在调试模式下编译(没有 -DNDEBUG),因此当使用空句柄时您会遇到断言失败。