PDA

View Full Version : سوال: کار با اشیا



m_zarie
سه شنبه 29 دی 1394, 12:53 عصر
با سلام خدمت دوستان محترم
من یه آرایه ای از اشیا دارم که چند تا property دارن.وقتی که مقدار یکی از property های یکی از اشیا رو تغییر میدم در صورتی که مقدار اون property در یه شی دیگه از آرایه هم مساوی با مقدار مذکور باشه property هر دو تا شی تغییر میکنه و شبیه به هم میشه.در صورتی که اینها دو شی متفاوت هستن.کسی میدونه دلیلش چیه؟ممنون

محمد آشتیانی
سه شنبه 29 دی 1394, 13:30 عصر
سلام
لطفا کدتون رو اینجا بذارید دوست گرامی

m_zarie
سه شنبه 29 دی 1394, 13:39 عصر
کدم طولانی هست ولی یه قسمتش که مشکل پیش میاد توش رو میذارم.در واقع یه قسمت از الگوریتم ژنتیک هست.کروموزم ها یه خصوصیت به اسم bodycrome دارن که از چهار قسمت تشکیل شده. هر با یه قسمت از اون تغییر میکنه.در ضمن تابع رندم رو اول برنامه گذاشتم.ممنون

public Cromosom[,] mutation(Cromosom[,] offspring)


{
double randpercent = 0;
int rnd = 0;


for(int i=0;i<Npop/2;i++)
for (int j = 0; j < 2; j++)
{
randpercent = generator.NextDouble();
if(randpercent<=pmutation)
{
rnd = generator.Next(1, 5);
if(rnd==1)
{
int n1 = generator.Next(0, n);
int n2 = generator.Next(0, n);
int count = 0;
int n10 = generator.Next(1, 10 * n);
for (int ii = 0; ii < n ; ii++)
{
if (n10 == offspring[i, j].bodyCrom[2][ii])
{
count++;


}
if (count != 0)
{
n10 = generator.Next(1, 10 * n);
ii = 0;
count = 0;
}


}
int count1 = 0;
int n20 = generator.Next(1, 10 * n);
for (int ii = 0; ii < n; ii++)
{
if (n20 == offspring[i, j].bodyCrom[2][ii])
{
count1++;


}
if (count1 != 0)
{
n20 = generator.Next(1, 10 * n);
ii = 0;
count1 = 0;
}


}
offspring[i, j].bodyCrom[2][n1] = n10;
offspring[i, j].bodyCrom[2][n2] = n20;
}


if(rnd==2)
{
int m1 = generator.Next(0, m);
int m2 = generator.Next(0, m);
int count2 = 0;
int m10 = generator.Next(1, 10 * m);
for (int ii = 0; ii < m; ii++)
{
if (m10 == offspring[i, j].bodyCrom[1][ii])
{
count2++;


}
if (count2 != 0)
{
m10 = generator.Next(1, 10 * m);
ii = 0;
count2 = 0;
}


}
int count4 = 0;


int m20 = generator.Next(1, 10 * m);
for (int ii = 0; ii < m; ii++)
{
if (m20 == offspring[i, j].bodyCrom[1][ii])
{
count4++;


}
if (count4 != 0)
{
m20 = generator.Next(1, 10 * m);
ii = 0;
count4 = 0;
}


}
offspring[i, j].bodyCrom[1][m1] = m10;
offspring[i, j].bodyCrom[1][m2] = m20;


}
if(rnd==3)
{
int p1 = generator.Next(0, p);
int p10 = generator.Next(1, 10 * p);
int count3 = 0;
for (int ii = 0; ii < p; ii++)
{
if (p10 == offspring[i, j].bodyCrom[0][ii])
{
count3++;


}
if (count3 != 0)
{
p10 = generator.Next(1, 10 * p);
ii = 0;
count3 = 0;
}


}


offspring[i, j].bodyCrom[0][p1] = p10;


}
if (rnd == 4)
{
int n3 = generator.Next(0, n);
int n4 = generator.Next(0, n);
int n30 = 0;
int n40 = 0;
for (int ii = 0; ii < 1; ii++)
{
n30 = generator.Next(1, m + 1);
if (n30 == offspring[i, j].bodyCrom[3][n3])
ii = ii - 1;
}
//if(n30==offspring[i,j].bodyCrom[3][n3])
for (int ii = 0; ii < 1; ii++)
{
n40 = generator.Next(1, m + 1);
if (n40 == offspring[i, j].bodyCrom[3][n4])
ii = ii - 1;
}


offspring[i, j].bodyCrom[3][n3] = n30;
offspring[i, j].bodyCrom[3][n4] = n40;
}
}
}
return offspring;
}

Davidd
سه شنبه 29 دی 1394, 14:49 عصر
سلام.
کدت طولانیه و تعریف کلاس موردنظر رو هم نذاشتی. اما این مشکلی که گفتی احتمالا به این خاطره که property موردنظر خودش یک شی هست به عبارت دیگر از نوع reference based هست. وقتی دو متغییر مثلا a و b از نوع reference based باشند یعنی نمونه های ساخته شده از یک کلاس باشند با اجرای دستور a=b ، هر دوی a و b به یک جا اشاره می کنند و هر کدومو تغییر بدی اون یکی هم تغییر میکنه. اگه میخای a و b مجزا باشند باید تک تک پراپرتی های a رو برابر مقدار نظیرش در b قرار بدی ( بعضی از کلاس ها تابع Clone دارند که همین کارو انجام میده یعنی مینویسی a=b.Clone() ) . راه دیگه هم اینه که در صورت امکان پراپرتی موردنظرتو از نوع struct تعریف کنی (struct ها بر خلاف کلاس ها value based هستند)

m_zarie
سه شنبه 29 دی 1394, 17:32 عصر
ممنون دوست عزیز.کلاسی که من تعریف کردم به این صورت هست.

public class Cromosom
{
public List<int>[] bodyCrom = new List<int>[4];

public float[] FitnessCrom = new float[3];
public int rank;
public float crowd;
public int np;
public float[]distance= new float[3];
public List<Cromosom>sp=new List<Cromosom>();
}

Davidd
چهارشنبه 30 دی 1394, 08:59 صبح
خواهش میکنم. پراپرتی BodyCrom از نوع لیست هست. موقعی که ماتریس دو بعدی offspring میسازی احتمالا این پراپرتی برای همه یا بعضی از اندیس ها یکیه ینی به یکجا اشاره می کنند. باید برای هر اندیس یک لیست جداگانه بنویسی. مثلا اگه lst یک لیست باشه و بنویسی offspring[1,1].BodyCrom=lst ; offspring[1,2].BodyCrom=lst اونوقت توی هر کدوم که lst تغییر کنه اون یکی هم تغییر میکنه. یه راهش اینه که اینطوری بنویسی
offspring[1,1].BodyCrom=lst.ToList() ;
offspring[1,2].BodyCrom=lst.ToList();