منتدى طلاب جامعة السودان المفتوحة
اسرة منتدى طلاب جامعة السودان المفتوحة تتمنى لكم اقامة طيبة برفقتها نرجو الدخول اذا كنت عضوا او التسجيل او زر اخفاء للزوار


المدير العام المنتدى : وليد عبدالوهاب احمد
 
الرئيسيةالمنشوراتالتسجيلدخول

شاطر | 
 

 المصفوفات فى السى

اذهب الى الأسفل 
كاتب الموضوعرسالة
ez2010zo

avatar

عدد المساهمات : 80
تاريخ التسجيل : 17/07/2010

مُساهمةموضوع: المصفوفات فى السى   السبت فبراير 25, 2012 8:13 pm



المصفوفة المتناثرة أو مصفوفة الأصفار [ Sparse Matrix(1) ]

بسم الله الرحمن الرحيم



المصفوفة المتناثرة أو مصفوفة الأصفار ( Sparse Matrix ) :


لو ألقينا نظرة على المصفوفة التالية التي تحوي 6 صفوف و6 أعمدة وتتكون من : 6x 6 = 36 عنصر :


سيتضح لنا من الوهلة الأولى أن أكثر عناصر هذه المصفوفة عبارة عن " أصفار " ؛ تسمى المصفوفة التي أكثر عناصرها أصفار بـمصفوفة الأصفار أو المصفوفة المتناثرة " Sparse Matrix " .. ومن الصعب علينا تحديد ما إذا كانت المصفوفة عبارة عن Sparse Matrix أو لا .. ولكن يتضح لنا ذلك عن طريق النظر ؛ ففي المصفوفة السابقة يوجد فقط 8 عناصر لا تساوي الصفر من أصل 36 عنصر ؛ بينما البقية كلها أصفار ..
تستخدم الـ Sparse Matrix لتوفير المساحة في الذاكرة حيث نستطيع تخزين العناصر الغير مساوية للصفر فيها ففقط ؛ وذلك من خلال استخدام مصفوفة وحيدة لكل عنصر من عناصرها يوجد 3 صفات هي : الصف والعمود والقيمة الخاصة به ؛ ويتم ذلك عن طريق استخدامنا لـStructure يحوي هذه الصفات ؛ كالتالي :


#define MAX_TERMS 10 /* maximum number of terms + 1 */
typedef struct {
int row ;
int col ;
int value ;
} sparse;
sparse a[MAX_TERMS] ;


ولكن يجب أن نراعي هنا أن ترتيب العناصر في هذه المصفوفة الوحيدة سيكون تابع لأحد هذه الصفات وهو الصف " row " و لابد من أن يكون تصاعدياً ..
ملاحظة : لتتعلم أكثر عن الـ Structures راجع هذا الدرس للأخ طلال : السجلات في سي " Structures in C "


إذن .. يتضح لدينا أن تعريف الـ Sparse Matrix كما هو موجود في قاموسنا كالتالي :
مصفوفة ذات بعد واحد تحوي الكثير من العناصر المتشابهة ، والتي غالباً ما تساوي صفر. ، لكل عنصر فيها ثلاث صفات : الصف ، العمود ، والقيمة التي تسند إليه .

* Sparse_Matrix : a set of triples < row , col , value > , where row & column are integers & from a unique combination , & value comes from the set item .
* Sparse_Matrix Create(max_row , max_col) ::= return a Sparse_Matrix that can hold up to max_item = max_row X max_col ,& whose maximum row size is max_row , & whose maximum column size is max_col.

ومن هنا نستطيع إعادة رسم الـ Sparse Matrix كما في الشكل التالي :


حيث أن a[0].row تحتوي عدد الأسطر الكلي للمصفوفة الأصلية ( في هذا المثال = 6 ) , كذلك a[0].col فهي تحوي عدد الأعمدة الكلي للمصفوفة الأصلية ( في هذا المثال = 6 ) , وأيضاً a[0].value عدد العناصر الغير مساوية للصفر فقط ( في هذا المثال = 8 ) .
ولكي نعرف رقم الصف لأي عنصر ننظر لـ Field row , وبالمثل إذا أردنا أن نعرف رقم العمود فننظر لـ Field col وستكون قيمة هذا العنصر مخزنة في Field value . والثلاثي < row , col , value > سيكون مرتب في المصفوفة على حسب الصفوف " تصاعدياً " كما ذكرنا سابقاً ..
ولكن كيف نستطيع كتابة شيفرة لإنشاء هذه المصفوفة بلغة السي ؟ هذا ما سنعرفه ان شاء الله خلال الاسطر التالية : سنقوم بالبداية بإنشاء Structure مشابه للمذكور أعلاه .. وسنفترض في مثالنا الحالي أن المصفوفة مكوّنة من 3 صفوف و3 أعمدة ..
وبعد ذلك نسمح للمستخدم بإدخال العناصر كمصفوفة عادية شريطة أن تكون أكثرها مساوية للصفر ونطبع المصفوفة بالطريقة التقليدية العادية :

Part1:



//------------------((( Sparse Matrix )))---------------
#include
#define MAX_TERM 10
typedef struct {
int row ;
int col ;
int val ;
} sparse;

int main()
{
sparse a[MAX_TERM]; // تعريف المصفوفة الصفرية
int b[3][3] ; // تعريف مصفوفة عادية
int i, j, count ;
printf("Plz. Enter the element one by one with press Enter :n");
for (i=0 ; i <3 ; i++ ) {
for (j=0 ; j <3 ; j++ ) {
scanf("%i",&b[i][j]) ;
} // end j loop
} // end i loop

//------------>--------------- -
printf("n**********************************nnNormal_Matrix is : n") ;
for (i=0 ; i <3 ; i++ ) {
for (j=0 ; j <3 ; j++ ) {
printf("%i t",b[i][j]) ;
} // end j loop
printf("n") ;
} // end i loop




بعد ذلك .. نقوم بإنشاء الـ Sparse Matrix ؛ نخزّن في البداية عدد الصفوف الكلي وعدد الأعمدة الكلي في كل من a[0].row و a[0].col .. ثم نضع عداداً = 1 كفهرس لكي نبدأ التخزين ..
نقوم بعمل Loop يمّر على كل عناصر المصفوفة العادية ويسأل ما إذا كان هذا العنصر مساوياً للصفر أما لا ؟
إذا اتضح أن العنصر لا يساوي الصفر .. نقوم بتخزين رقم الصف الموجود فيه هذا العنصر وكذلك رقم العمود ثم نخزّن قيمة العنصر باستخدام العداد الذي جعلنا قيمته =1 كفهرس لأول عنصر يقابلنا غير مساوي للصفر .. ثم نزيد قيمة العداد بواحد لكي يفهرس العنصر المخزن الجديد .. وهكذا إلى أن ننتهي من جميع عناصر المصفوفة الأصلية .
الآن قمنا بتخزين جميع القيم الغير مساوية للصفر في الـ Sparse Matrix ولكن يتبقى Field واحد لم نخزّن به شئ .. أتعلمون ما هو ؟
إنه الـ Field الخاص بعدد العناصر الغير مساوية للصفر في المصفوفة الأصلية (a[0].val ) .. ونستطيع معرفة عدد العناصر الغير مساوية للصفر من خلال العداد الذي فهرس العناصر ..
ولكن نلاحظ هنا أن هذا العداد داخل Loop عندما انتهى التخزين قد زادت قيمته بواحد على عدد العناصر الغير مساوية للصفر ؛ فيجب علينا أن نقوم بانقاص قيمته بمقدار واحد ثم نخزنها في a[0].val ...
إذن ؛ نستطيع طباعة المصفوفة المتناثرة الناتجة لدينا .. وذلك بإضافة الكود التالي للكود السابق :


Part2:



//------------>----------------
a[0].row=3 ;
a[0].col=3 ;
count=1;
for (i=0 ; i <3 ; i++ ){
for (j=0 ; j <3 ; j++ ){
if ( b[i][j]!= 0 ){
a[count].row=i ;
a[count].col=j ;
a[count].val=b[i][j] ;
count++;
} // end if
} // end j loop
} // end i loop
a[0].val=count-1 ;
printf("n*******************nnSparse_Matrix is : nrowtcoltvaluen---------------------n") ;
for ( i=0 ; i printf("%it",a[i].row) ;
printf("%it",a[i].col) ;
printf("%in",a[i].val) ;

}

return 0;

}// end of main




وهكذا .. نكون قد وفرنا الذاكرة لدينا عند استخدام مثل هذه المصفوفات في حل المشكلات الكبيرة ..
الرجوع الى أعلى الصفحة اذهب الى الأسفل
ez2010zo

avatar

عدد المساهمات : 80
تاريخ التسجيل : 17/07/2010

مُساهمةموضوع: رد: المصفوفات فى السى   السبت فبراير 25, 2012 8:14 pm



تدوير المصفوفة المتناثرة [ Sparse Matrix(2) ]

بسم الله الرحمن الرحيم



تدوير المصفوفة المتناثرة ( Transposing a Sparse Matrix )



بعد أن تعرفنا على المصفوفة المتناثرة ( مصفوفة الأصفار ) [ Sparse_Matrix ] نتعرف الآن على طريقة تدويرها ؛ ونعني بتدويرها: تبديل الصفوف بالأعمدة في السجل.
بمعنى أن كل عنصر a[i][j] في المصفوفة المتناثرة سيؤول إلى العنصر b[j][i] في مصفوفة التدوير المقابلة لها. والشكل التالي يوضح التدوير للمصفوفة المتناثرة التي اعتمدناها في شرح الدرس السابق :



لنفكر قليلاً كيف يمكننا فعل ذلك بمصفوفة ذات بعد واحد ؟

أول ما سنستنجد به هو ترتيب المصفوفة المتناثرة ؛ حيث أنها مرتبة ترتيباً تصاعدياً عن طريق الصفوف ..

وهذا صحيح ولكن لنفكر للحظة كيف لنا استخدام هذا الترتيب التصاعدي في الصفوف كي نصل إلى ترتيب تصاعدي آخر ولكن عن طريق الأعمدة ؟



لنرى معاً :

لو قلنا أنه بما أننا فهرسنا مصفوفة الأصفار تصاعدياً باستخدام الصفوف ؛ فإننا سنستفيد من هذا الترتيب التصاعدي في عملية تدوير المصفوفة كما توضح الخوارزمية التالية :


For each row i

Take element < i , j , value > and store it as element < j , i , value > of the transpose ;



لو جدنا في هذه الطريقة أن الترتيب سيبقى تصاعدياً ولكن من ناحية الأعمدة - حيث أننا في مصفوفة التدوير بدلنا الصفوف بالأعمدة - وبذلك لن نحصل على مصفوفة مرتبة ترتيباً تصاعدياً من ناحية الصفوف !؛ ولو طبقنا الخوارزمية السابقة على المثال الذي شرحنا عليه مصفوفة الأصفار ؛ فسنحصل على التالي :

(0 , 0 , 15 ) ستصبح (0 , 0 , 15 )
( 0 , 3 , 22 ) ستصبح (3 , 0 , 22 )
(0 , 5 , -15 ) ستصبح ( 5 , 0 , -15 )
(4 , 0 , 91 ) ستصبح (0 , 4 , 91 )
(5 , 2 , 28 ) ستصبح (2 , 5 , 28 )
وهكذا



النتيجة: مصفوفة مرتبة تصاعدياً من ناحية الأعمدة ، بينما نحتاج إلى مصفوفة التدوير مرتبة تصاعدياً من ناحية الصفوف كما ذكرنا ذلك !!

الطريقة التي ستوصلنا إلى ترتيب تصاعدي جديد عن طريق الصفوف ، هي تثبيت العمود إبتداءاً من أصغر قيمة (صفر) والدوران حوله بجميع القيم الممكنة للصفوف (ابتداءاً من صفر إلى عدد الصفوف الكلي المخزن في a[0].row من مصفوفة الأصفار) ، وهكذا لكل عمود على حدة ..

ربما تساعدك الخوارزمية التالية لمعرفة ديناميكية الحل :


For all elements in column j

Place element < i , j , value > in element < j , i , value > ;

لعمل ذلك ، سنستخدم Tow For Loops & If statement ولا ننسى أن نستخدم عداد جديد "currentb مثلاً " للفهرسة ، كما توضح الشيفرة التالية:

//----->------

void Transpose (sparse m[MAX_TERM] , sparse n[MAX_TERM] )

{

int i , j , k , currentb ;

k = m[0].val ; // total number of elements.

n[0].row = m[0].row ; // rows in n = columns in m .

n[0].col = m[0].col ; // columns in n = rows in m .

n[0].val = k ;

if( k > 0 ){ /* non zero matrix */

currentb = 1 ;

for (i=0 ; i <= m[0].col ; i++ ) {

/* transpose by the columns in m */

for (j=1 ; j <= k ; j++ ) {

/* find elements from the current column */

if(m[j].col == i){

/* element in curret column , add it to n */

n[currentb].row = m[j].col ;

n[currentb].col = m[j].row ;

n[currentb].val = m[j].val ;

currentb++ ;

} // end if

} // end j loop

} // end i loop



printf( "n**************nnTranspose of a Sparse_Matrix is : nrowtcoltvaluen------------n" );

for ( i=0 ; i<= n[0].val ; i++ ){

printf("%it",n[i].row );

printf("%it",n[i].col );

printf("%in",n[i].val );

} // end i loop

} // end if

} // end of function : Transpose.





الزمن الكلي لتنفيذ هذه الـ For Loops هو ببساطة ناتج ضرب عدد أعمدة مصفوفة الأصفار في عدد عناصرها ، وهو وقت قليل بالمقارنة مع وقت تدوير المصفوفة بطريقة تقليدية بدون استخدام الـ For Loops .

جرب هذه الشيفرة التي تعتبر تطبيق كلي لما تعلمناه في درسي مصفوفة الأصفار :



//------------------((( Sparse Matrix )))---------------

#include "stdio.h"

#define MAX_TERM 10

typedef struct {

int row ;

int col ;

int val ;

} sparse;

void Transpose (sparse m[MAX_TERM] ,sparse n[MAX_TERM] ) ;

void main()

{

sparse a[MAX_TERM] ,trans_a[MAX_TERM];

int b[3][3] ;

int i, j, count ;

printf("Plz. Enter the element one by one with press Enter :n");

for (i=0 ; i <3 ; i++ ) {

for (j=0 ; j <3 ; j++ ) {

scanf("%i",&b[i][j]) ;

} // end j loop

} // end i loop

//------------>----------------

printf("n***************************nnNormal_Matrix is : n") ;

for (i=0 ; i <3 ; i++ ) {

for (j=0 ; j <3 ; j++ ) {

printf("%i t",b[i][j]) ;

} // end j loop

printf("n") ;

} // end i loop

//------------>----------------

a[0].row=3 ;

a[0].col=3 ;

count=1;

for (i=0 ; i <3 ; i++ ){

for (j=0 ; j <3 ; j++ ){

if ( b[i][j]!= 0 ){

a[count].row=i ;

a[count].col=j ;

a[count].val=b[i][j] ;

count++;

} // end if

} // end j loop

} // end i loop

a[0].val=count-1 ;

printf("n***************nnSparse_Matrix is : nrowtcoltvaluen-----------n")
;

for ( i=0 ; i
printf("%it",a[i].row) ;

printf("%it",a[i].col) ;

printf("%in",a[i].val) ;

}

//-----------------------

Transpose( a , trans_a);

}

//----->------

void Transpose (sparse m[MAX_TERM] , sparse n[MAX_TERM] )

{

int i , j , k , currentb ;

k = m[0].val ; // total number of elements.

n[0].row = m[0].row ; // rows in n = columns in m .

n[0].col = m[0].col ; // columns in n = rows in m .

n[0].val = k ;

if( k > 0 ){ /* non zero matrix */

currentb = 1 ;

for (i=0 ; i <= m[0].col ; i++ ) {

/* transpose by the columns in m */

for (j=1 ; j <= k ; j++ ) {

/* find elements from the current column */

if(m[j].col == i){

/* element in curret column , add it to n */

n[currentb].row = m[j].col ;

n[currentb].col = m[j].row ;

n[currentb].val = m[j].val ;

currentb++ ;

} // end if

} // end j loop

} // end i loop



printf( "n************nnTranspose of a Sparse_Matrix is : nrowtcoltvaluen---------n" );

for ( i=0 ; i<= n[0].val ; i++ ){

printf("%it",n[i].row );

printf("%it",n[i].col );

printf("%in",n[i].val );

} // end i loop

} // end if

} // end of function : Transpose.

الرجوع الى أعلى الصفحة اذهب الى الأسفل
 
المصفوفات فى السى
الرجوع الى أعلى الصفحة 
صفحة 1 من اصل 1

صلاحيات هذا المنتدى:لاتستطيع الرد على المواضيع في هذا المنتدى
منتدى طلاب جامعة السودان المفتوحة :: منتدى لغات البرمجه :: منتدى c++ &c-
انتقل الى: