Использование GLPK в цикле parallel_for

Я хочу запустить решатель LP в GLPK в цикле parallel_for. Все проблемы не зависят друг от друга, поэтому не должно быть никаких помех.

Вот пример кода, который завершается с ошибкой, это, по сути, пример кода из викибук glpk, но заключенный в цикл parallel_for. Любая помощь будет оценена

//#include <stdio.h>            /* C input/output                       */
//#include <stdlib.h>           /* C standard library                   */
#include <iostream>
#include <glpk.h>             /* GNU GLPK linear/mixed integer solver */
#include <ppl.h>

using namespace concurrency;
using namespace std;

void main()
{
parallel_for(0, 10, [](int i){
/* declare variables */
glp_prob *lp;
int *ia = new int[4];
int *ja = new int[4];
double *ar = new double[4];
double z, x1, x2;/* create problem */
lp = glp_create_prob();
glp_set_prob_name(lp, "minimax");
glp_set_obj_dir(lp, GLP_MAX);/* fill problem */
glp_add_rows(lp, 2);
//glp_set_row_name(lp, 1, "p");
glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 1.0);
//glp_set_row_name(lp, 2, "q");
glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 2.0);glp_add_cols(lp, 2);
//glp_set_col_name(lp, 1, "x1");
glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);
glp_set_obj_coef(lp, 1, 0.6);
//glp_set_col_name(lp, 2, "x2");
glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);
glp_set_obj_coef(lp, 2, 0.5);ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */
ia[2] = 1, ja[2] = 2, ar[2] = 2.0; /* a[1,2] = 2 */
ia[3] = 2, ja[3] = 1, ar[3] = 3.0; /* a[2,1] = 3 */
ia[4] = 2, ja[4] = 2, ar[4] = 1.0; /* a[2,2] = 1 */
glp_load_matrix(lp, 4, ia, ja, ar);/* solve problem */
glp_simplex(lp, NULL);
/* recover and display results */
z = glp_get_obj_val(lp);
x1 = glp_get_col_prim(lp, 1);
x2 = glp_get_col_prim(lp, 2);
printf("z = %g; x1 = %g; x2 = %g\n", z, x1, x2);
/* housekeeping */
glp_delete_prob(lp);
glp_free_env();
});
system("pause");
}

0

Решение

Ты звонишь glp_free_env изнутри каждого потока, в то время как библиотека все еще активно выполняет работу в других потоках. Это не сработает — вы дергаете коврик из-под ниток, усердно работая ..

Вместо этого вызывайте его только после того, как все потоки завершили вычисления (присоединитесь к ним). В этом простом примере вы, вероятно, можете вообще пропустить этап очистки.

1

Другие решения

Я нашел проблему. Проблема связана с исходным кодом GLPK, есть пара подпрограмм, которые не могут быть повторно введены, вызывая некоторые большие проблемы. Это задокументировано здесь: http://en.wikibooks.org/wiki/GLPK/Using_the_GLPK_callable_library . Существует также исправление, но оно требует его восстановления. Обратите внимание, что это работает только с GLPK версии 4.50 и старше, более новые версии имеют немного другой макет.

Хотя Бен был полностью прав, внесение этого изменения в библиотеку решает все проблемы и позволяет освободить среду внутри цикла.

1

По вопросам рекламы [email protected]