Вычислительные схемы метода оптимального разделения графов на основе конструктивного перечисления разбиений множеств их вершин




 

Минимум функции Tk =max((Qi + Ri), где i=1, 2, …, k), ввиду её монотонности достигается при np=n, номер класса эквивалентности разбиений, а n – число вершин в разделяемом графе. Пусть, как и прежде, задан неориентированный взвешенный граф G(V,E) с числом вершин равным n. Этот граф является математической моделью решения некоторой задачи. В памяти компьютера этот граф задаётся матрицей смежности вершин A[n][n], диагональные элементы которой представляют собой временную сложность подзадач, которые могут быть решены параллельно на нескольких процессорах или последовательно на однопроцессорной платформе, а все остальные элементы этой матрицы моделируют временные сложности коммуникационных операций. При решении задачи с использованием единственного процессора коммуникационные затраты отсутствуют. И временная сложность решения всей задачи T1 определяется суммой диагональных элементов матрицы A[n][n]: mSA=A[0][0]; for(j1=1;j1<n;j1++)mSA+=A[j1][j1]; положить T1= mSA. Если теперь T1 разделить на заданный коэффициент ускорения S, то мы получим верхнюю границу для значений функции Tk, соответствующих искомым (допустимым) разбиениям. Добавим к этому ограничению условие «использовать минимальное число процессоров» и получим наиболее практически значимую постановку задачи оптимального разделения взвешенного графа: определить разбиение множества вершин графа P={V1,…,Vk}, на минимальное число подмножеств k, такое для которого выполняются условия достижения заданного ускорения (1.1).

Монотонное убывание значений функции Tk при возрастании числа подмножеств в разбиениях позволяет использовать базовый алгоритм Eq2_1 как в вычислительной схеме последовательного поиска (будем отождествлять её с алгоритмом Eq2_1), так и в алгоритме двоичного поиска минимального разбиения взвешенного графа, при котором обеспечивается выполнение условия (1.1) [3]. Ниже будем именовать вычислительную схему двоичного поиска алгоритмом Eq3_1. Сначала рассмотрим псевдокод алгоритма Eq2_1. Он состоит из следующих шагов:

1. Пусть задана матрица A[n][ n] и коэффициент ускорения kp.

2. Вычислить mSA=A[0][0]; for(j1=1;j1<n;j1++)mSA+=A[j1][j1]; mSA/=kp;

3. Установить значения вектора спецификации разбиения pPsi и характеристического вектора pChi в соответствии с разбиением множества X, состоящим из единственного класса, и: for(i=0;i<n;i++) Chi[i]=pPsi[i]=1. Положить ic=0; np= 1.

4. Для анализа первого класса эквивалентности выполнить 5-8:

if(np < 2)

{

5. Проверка, не достаточно ли одного процессора: увеличить значение счётчика и определить текущее (начальное) значение minmaxSA:

ic1++;

for(i=0;i<n;i++) pChi[i]=pPsi[i]=1;

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

6. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата: if(mSA>=maxSA) goto m_result;

7. Выполнить minmaxSA=maxSA;

8. Увеличить текущий номер класса эквивалентности разбиений: np++;}

//************Начало основного цикла

9. Положить nf=n и выполнять 10— 30 для всех оставшихся классов эквивалентности разбиений (np=2, 3, …, n):

while(np<=nf)

{

10. Определить вектор спецификаций для нового класса эквивалентностей разбиений и построить первый характеристический вектор разбиения в этом классе: ii=np; for (i=n-1; i>0; i--)

{if(ii>1){pChi[i]=pPsi[i]=ii; ii--;}else pChi[i]=pPsi[i]=1; }

11. Увеличить значение счётчика и определить minSA:

ic1++;if(ic1>999999999){ic2++;ic1=0;}

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

12. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата: if(mSA>=maxSA) goto m_result;

13. Выполнить: if(minmaxSA>maxSA)minmaxSA=maxSA;

// Переменная minmaxSA позволяет монотонное убывание maxSA

14. Положить:i=n-1;

15. Повторять 16 - 27 пока есть ещё не рассмотренные разбиения в текущем классе эквивалентности:разбиений: while(i>0){

//Change PS***************************

16. Изменить вектор спецификаций, выполнив действия 17-21:

for (i=n-1; i>0; i--) {

17. В текущем классе эквивалентности есть нерассмотренная спецификация?

if((pPsi[i]==pPsi[i-1])&&(pPsi[i]<np))

18. Да, тогда построить новый вектор pPsi:

{pPsi[i]++; pChi[i]=pPsi[i]; k=np;

for(ii=n-1; ii>i; ii--) {pPsi[ii] =k; if(k>pPsi[i]) k--;}

19. Для нового вектора pPsi построить первый характеристический вектор разбиения pCh:

for(ii=1; ii<n; ii++)if(pPsi[ii]==pPsi[ii-1])pChi[ii]=1;else pChi[ii]=pPsi[ii];}

20. Увеличить значение счётчика и определить minSA:

ic1++;if(ic1>999999999){ic2++;ic1=0;}

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

21. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата: if(mSA>=maxSA) goto m_result;

2.2. Выполнить: if(minmaxSA>maxSA)minmaxSA=maxSA;

23. Прервать цикл «for i »: break;} // if(pPsi[i]==pPsi[i-1])&&pPsi[i]<np)

} //end for i

24. Если цикл «for i» был прерван (был построен новый вектор pPsi), то выполнить построение нового характеристического вектора pChi (действия 25 - 29): if(i>0) {

25. Выполнить: ii=n-1;

while(ii>0) { if(pChi[ii]<pPsi[ii]) {pChi[ii]++; k=ii; k++;

while(k<n) { if(pPsi[k]==pPsi[k-1]) {pChi[k]=1; } k++;}

ii=n-1;

26. Увеличить значение счётчика и определить minSA:

ic1++;if(ic1>999999999){ic2++;ic1=0;}

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

27. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата: if(mSA>=maxSA) goto m_result;

28. if(minmaxSA>maxSA)minmaxSA=maxSA;

}//end if(pChi[j]<pPsi[j])

29. Выполнить: else ii--;

}// end while(ii>0)

// Конец изменений pChi

}// end if(i>0)

} //end while(i>0)

30. Выполнить:np++;

}//end while(np<=n)

//*********************Конец основного цикла

m_result: 31. Выполнить:

finish = clock();duration = (double)(finish - start) / CLOCKS_PER_SEC;

32. Вывести номер экспериментальной точки " N= jj ", число просмотренных вариантов " NN= ic2* ic1”, время поиска минимального разбиения множества вершин "duration", номер класса эквивалентности "np", в котором найдено решение, значение функции "Tk= maxSA", характеристический вектор разбиения множества вершин "pChi", который представляет собой найденное решение.

33. Стоп.//Конец описания алгоритма.

 

Разработка алгоритма Eq3_1 состояла в объединении имеющей общее назначение вычислительной схемы двоичного поиска и поиска экстремального разбиения множества, которая была выше и алгоритма вычисления функции F3. Ниже приводится псевдокод этого алгоритма.

1. Пусть задана матрица A[n][ n] и коэффициент ускорения kp.

2. Вычислить mSA=A[0][0]; for(j1=1;j1<n;j1++)mSA+=A[j1][j1]; mSA/=kp;

3. Выполнить: ic1=ic2=0;np=1;

4. Вывести " mSA=”, inSA;

5. Выполнить: start = clock();

6. Выполнить генерацию первого разбиения: for(i=0;i<n;i++) pChi[i]=pPsi[i]=1;

7. Обработать первое разбиение, выполнив действия 8 - 10:

if(np < 2)

{

8. Выполнить: for(i=0;i<n;i++) pChi[i]=pPsi[i]=1;

ic1++;

9. Вычислить значение функции S= maxSA для первого разбиения: maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

10. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата:

if(minSA>=maxSA){ minmaxSA=maxSA;minnp=np;

for(j1=0; j1<n; j1++) minpChi[j1]= pChi[j1];

goto m3_result;}

} // if(np < 2)

//************Начало основного цикла

11. Вычислить np: nn1=2; nn2=n; np=(nn1+nn2)/2;

12. Выполнить:

while(nn2>nn1)

{// Изменить pPsi*****************************

13. Определить вектор спецификаций для нового класса эквивалентностей разбиений и построить первый характеристический вектор разбиения в этом классе: ii=np; for (i=n-1; i>0; i--){ if(ii>1){pChi[i]=pPsi[i]=ii; ii--;}else pChi[i]=pPsi[i]=1; }

14. Увеличить значение счётчика и определить minSA:

ic1++;if(ic1>999999999){ic2++;ic1=0;}

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

15. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата:

if(mSA>=maxSA){ minmaxSA=maxSA;minnp=np;

for(j1=0; j1<n; j1++) minpChi[j1]= pChi[j1]; goto m2_result;}

16. Положить: i=n-1;

17. Повторять 18 - 27 пока есть ещё не рассмотренные разбиения в текущем классе эквивалентности:

while(i>0)

{

//Change PS***************************

18. Изменить вектор спецификаций, выполнив действия 19-23:

for (i=n-1; i>0; i--)

{

19. В текущем классе эквивалентности есть нерассмотренная спецификация?

if((pPsi[i]==pPsi[i-1])&&(pPsi[i]<np))

20. Да, тогда. Построить новый вектор pPsi:

{pPsi[i]++; pChi[i]=pPsi[i]; k=np;

for(ii=n-1; ii>i; ii--) {pPsi[ii] =k; if(k>pPsi[i]) k--;}

21. Для нового вектора pPsi построить первый характеристический вектор разбиения pCh:

for(ii=1; ii<n; ii++){if(pPsi[ii]==pPsi[ii-1])pChi[ii]=1;else pChi[ii]=pPsi[ii];} 22. Увеличить значение счётчика и определить minSA:

ic1++;if(ic1>999999999){ic2++;ic1=0;}

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

23. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата:

if(mSA>=maxSA){ minmaxSA=maxSA;minnp=np;

for(j1=0; j1<n; j1++) minpChi[j1]= pChi[j1];

goto m2_result;}

24. Выполнить: break; } // if(pPsi[i]==pPsi[i-1])&&pPsi[i]<np)

} //end for i

25. Если цикл «for i» был прерван (был построен новый вектор pPsi), то выполнить построение нового характеристического вектора pChi (действия 26 – 29): if(i>0)

{

26. Выполнить ii=n-1; while(ii>0)

{ if(pChi[ii]<pPsi[ii]) {pChi[ii]++; k=ii; k++;

while(k<n){if(pPsi[k]==pPsi[k-1]) {pChi[k]=1; }k++;}

ii=n-1;

27. Увеличить значение счётчика и определить minSA:

ic1++;if(ic1>999999999){ic2++;ic1=0;}

maxSA=0; for(j1=0; j1<np; j1++)SA[j1]=0;

for(j1=0; j1<np; j1++){for(j2=0; j2<n; j2++){

if((j1+1)==pChi[j2]){SA[j1]+=A[j2][j2];

for(j3=0; j3<n; j3++)if(pChi[j3]!=(j1+1))SA[j1]+= A[j2][j3];}}

if(maxSA<SA[j1])maxSA=SA[j1];}

28. Если найдено разбиение, обеспечивающее требуемое ускорение, то перейти к обработке результата:

if(mSA>=maxSA){ minmaxSA=maxSA;minnp=np;

for(j1=0; j1<n; j1++) minpChi[j1]= pChi[j1];

goto m2_result;}

}//end if(pChi[j]<pPsi[j])

29. Выполнить: else ii--;

}// end while(ii>0)

//Конец изменений pChi**************************

}// end if(i>0)

} //end while(i>0)

30. Вычислить новое значение np: m2_result:if(mSA>=maxSA)nn2=np; else nn1=np+1; np=(nn1+nn2)/2;

}//end while(nn2>nn1)

//*********************End main cycle

31. Выполнить: m3_result:finish = clock();duration = (double)(finish - start) / CLOCKS_PER_SEC;

32. Вывести номер экспериментальной точки " N= jj ", число просмотренных вариантов " NN= ic2* ic1”, время поиска минимального разбиения множества вершин "duration", номер класса эквивалентности "np", в котором найдено решение, значение функции "S= maxSA", характеристический вектор разбиения множества вершин " minpChi ", который представляет собой найденное решение.

33. Стоп.//Конец описания алгоритма

Описанные в данном разделе алгоритмы были реализованы в виде консольных программ, которые обеспечили их экспериментальное исследование. Результаты этого исследования рассматриваются в следующем разделе.

Для проведения вычислительного эксперимента с алгоритмами Eq2_1, Eq3_1, их программные реализации были объединены в специальную тест-программу. Это позволило выполнять обработку этими алгоритмами одних и тех же матриц смежности взвешенных графов, которые генерировались с использованием равномерно распредел1нных псевдослучайных чисел. Основные результаты вычислительного эксперимента с указанной тест-программой представлены в таблице 3

Таблица 3. Сравнение алгоритмов Eq2_1, Eq3_1 при n= 12, kf=10, kp=3

  N   mSA Последовательный поиск Двоичный поиск (Eq3_1)
np maxSA Время, с np maxSA Время, с
  455,691   451,529 10,469   451,529 1,828
  524,902   523,995 5,141   523,995 5,25
  477,854   471,153 10,187   471,153 2,11
  518,264   517,727 4,765   517,727 4,672
  493,197   492,011 8,266   492,011 4,984
  501,415   498,243 8,141   498,243 8,141
  518,372   517,691     517,691  
  504,544   501,87 5,422   501,87 5,609
  480,443   472,134 10,171   472,134 2,094
  501,598   501,512 8,156   501,512 4,968
Среднее время поиска = 7,7718 Среднее время поиска = 4,6656

 

Данные приведённые в таблице 6 свидетельствуют о том, что двоичный поиск оказывается быстрее усовершенствованного последовательного поиска в 1,665766 раз в среднем.

 

ВЫВОДЫ

 

В результате вычислительного эксперимента показано, что минимальное значение временной сложности параллельных вычислений (функция Tk) монотонно убывает с увеличением номера класса эквивалентности разбиений множества вершин взвешенного графа. Эта монотонность имеет места при достаточно широком диапазоне изменений основных параметров, от которых зависит функция Tk. Монотонность функции Tk позволила использовать базовый алгоритм Eq2_1 как в вычислительной схеме последовательного поиска (будем отождествлять её с алгоритмом Eq2_1) так в алгоритме двоичного поиска минимального разбиения взвешенного графа, при котором обеспечивается коэффициент ускорения в среднем равный 1,665766. Разработанный метод оптимального разделения взвешенных графов, основанный на использовании алгоритма Eq3_1, обеспечивает эффективное решение задачи определения минимального числа процессоров, необходимых для реализации параллельных вычислений с заданным ускорением относительно последовательных вычислений.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2020-10-21 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: