2013-02-09 6 views
2

У меня есть генетический алгоритм, и я пытаюсь распараллелить генерацию населения. Мой реальный код:Проблемы Parfor с формированием популяции

Q = []; 
parfor i=1:halfPop 
    pa = P(select(f),:); 
    pb = P(select(f),:); 
    ... 
    Q = [Q; pa; pb]; 
end 

Matlab дает мне ошибку Временная переменная Q в parfor не инициализирован.

Так я переписал это так:

Q = []; 
parfor i=1:halfPop 
    pa = P(select(f),:); 
    pb = P(select(f),:); 
    Q(i,:) pa; 
    Q(i+halfPop,:) pb; 
end 

Но теперь я получаю ошибку Переменная Q в parfor не могут быть классифицированы.. В редакторе MATLAB мне сообщается, что я не могу индексировать двумя разными способами одну и ту же матрицу внутри parfor.

Что мне делать?

+0

Почему у вас есть это внутри 'parfor' цикла? Является ли 'select' функцией, которая занимает много времени? Если нет, цикл 'for' может быть быстрее. – Jonas

+0

Ну, я упростил код для задавания вопроса, на самом деле есть пара других занимающих много времени вещей – Enoon

ответ

2

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

Чтобы исправить это, вы можете определить две переменные: Qa и Qb, которые вы можете комбинировать после окончания цикла parfor.

[Qa,Qb] = deal(zeros(halfPop,size(P,2))); 
parfor i=1:halfPop 
    pa = P(select(f),:); 
    pb = P(select(f),:); 
    Qa(i,:) = pa; 
    Qb(i,:) = pb; 
end 

Q = zeros(2*halfPop,size(P,2)); 
Q(1:2:end,:) = Qa; 
Q(2:2:end,:) = Qb; 
+0

Спасибо, это решение, которое я придумал отдельно. Это не самый быстрый, но он работает. – Enoon

0

Много разных вариантов, в зависимости от того, как pa и pb имеют одинаковый размер. Matlab хочет удостовериться, что нет риска перезаписи данных (из-за отсутствия лучшего термина), и он не может установить, что в этом случае. По существу, вы можете писать в матрицу только один раз за итерацию и выполняться в соответствии с тем, что, по ее мнению, является «хорошей практикой».

Мое решение:

Q = zeros(halfPop,size([pa pb]); 
parfor i=1:halfPop 
    pa = P(select(f),:); 
    pb = P(select(f),:); 
    Q(i,:)= [pa pb]; 
end 
+0

Не будет ли этот код поставить pa и pb на ту же строку? – Enoon

+0

@ Конечно, но вы знаете, где все остальное, тогда вы можете реорганизовать Q в свое сердце. Ваш вопрос организует Q двумя разными способами, поэтому я не был уверен, как вы хотите, чтобы Q был настроен. – Rasman

+0

Вижу, спасибо за объяснение! – Enoon

1

«Уменьшение конкатенации» вы пытаетесь должен работать, если вы сделаете конкатенацию с одним операндом, как так

tmp = [pa; pb]; 
Q = [Q; tmp]; 
Смежные вопросы