کلیدستان

نسخه‌ی کامل: سوال : صفر کردن درصد مشخصی از عناصر یک ماتریس سه بعدی به صورت رندوم
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
سلام
من این کد رو برای حذف کردن درصدی از ماتریس داده سه بعدی نوشتم ولی اجرا نمیشه . میشه کمک کنید .
من یک شرط  while  تعیین کردم برای درصدگیری از ماتریس ، البته چون ماتریس سه بعدی است ، یک ماتریس one تعریف کردم که همزمان با صفر شدن ستون های ماتریس اصلی سه بعدی ، همان درایه در ماتریس one صفر میشه و درصدگیری روی ماتریس one  اعمال میشه . درایه ها به صورت تصادفی با دستور randi  تعیین میشن .
ولی با اجرای برنامه خروجی percent رو برابر صفر نمایش میده و انگار اصلا حلقه while رو نمیخونه . داده ها در سایت فورشیر آپلود و در پیوست هستند.


کد:
m=d_x_true;
m_size=size(m);
% Eliminate Random Traces 
delete=30;   % in percent
number_zero=(m_size(2)*m_size(3)*delete)/100;
one=ones(m_size(2),m_size(3));
percent_eliminate=((numel(one)-nnz(one))/(numel(one))*100);
while (percent_eliminate == delete)
    random_x= randi([1,121],1,1);
    random_y=randi([1,121],1,1);
    m_noise(:,random_x,random_y)=0;
    one(random_x,random_y)=0;
    percent_eliminate=((numel(one)-nnz(one))/(numel(one))*100);
end
percent_eliminate

فایل با پسوند mat.  در سایت فورشیر آپلود شده است .
http://www.4shared.com/file/bmNmmHiE/3d_3c_synth.html 
سلام . 
کداتون به هم ریخته بود ، مجبور شدم کدها رو ویرایش کنم .
شما باید به جای == از =~ استفاده کنی . اصلا حلقه while اجرا نمیشه .
تازه یک مورد مهمتر ، ممکنه percent_eliminate دقیقا برابر 30 نشه . مثلا با توجه به تعداد درایه ها ، بشه 30.1 .
دوست من ، هم کدها و هم ارسال هاتون در این انجمن رو با حوصله بنویسید . تا به مشکل برخوردید سریع اینجا مطرح نکنید بلکه وقت بگذارید و اگر بعد از یکی دو روز به نتیجه نرسیدید بیاید و اینجا مطرح کنید . سود این روش به خودتون میرسه و مطمئنا ما هم از چیزهایی که در رویارویی با این مشکلات یاد میگیرید ، بهره خواهیم برد . 
همیشه هم روشتون رو اول روی ماتریس های کوچک اجرا کنید تا دیدتون باز بشه و کورکورانه با ماتریس های بزرگ کار نکنید وگرنه بهتون قول میدم همه چی هم که درست به نظر بیاد باز هم ممکنه یه جایی رو اشتباه کرده باشید .
موفق باشی دوست عزیز .

 
(۱۳۹۲/۰۲/۱۰, ۰۳:۱۵ ب.ظ)'admin' نوشته: [ -> ]سلام . 
کداتون به هم ریخته بود ، مجبور شدم کدها رو ویرایش کنم .
شما باید به جای == از =~ استفاده کنی . اصلا حلقه while اجرا نمیشه .
تازه یک مورد مهمتر ، ممکنه percent_eliminate دقیقا برابر 30 نشه . مثلا با توجه به تعداد درایه ها ، بشه 30.1 .
دوست من ، هم کدها و هم ارسال هاتون در این انجمن رو با حوصله بنویسید . تا به مشکل برخوردید سریع اینجا مطرح نکنید بلکه وقت بگذارید و اگر بعد از یکی دو روز به نتیجه نرسیدید بیاید و اینجا مطرح کنید . سود این روش به خودتون میرسه و مطمئنا ما هم از چیزهایی که در رویارویی با این مشکلات یاد میگیرید ، بهره خواهیم برد . 
همیشه هم روشتون رو اول روی ماتریس های کوچک اجرا کنید تا دیدتون باز بشه و کورکورانه با ماتریس های بزرگ کار نکنید وگرنه بهتون قول میدم همه چی هم که درست به نظر بیاد باز هم ممکنه یه جایی رو اشتباه کرده باشید .
موفق باشی دوست عزیز .

 


 
حرف شما درست ولی وقت من کمه ، از الان تا روز یکشنبه فرصت دارم بعد باید استادم رو ببینم ، و این مشکل یک قسمت از یک برنامه است نه کل مشکل من ، بر اساس اون باید برای 10 تا 90 درصد حذف شدگی ستون ها ،  یک الگوریتم رو چک کنم و رسم کنم و دو الگوریتم دیگه هم باید بنویسم که مقداری با برنامه اول متفاوت هستند و ریاضیات دیگه ای دارند .
بله درک می کنم وقتتون کمه . 
با توجه به دو نکته ای که گفتم ، این روش کدنویسی جواب نمیده . 
سعی می کنم یک کد مناسب بنویسم . 
اینم از کد متلب :

کد:
clear all
close all
clc

delete=4;

A=ones(3,2,3);
A_size=size(A)

deleted_before=zeros(1,2);
deleted_number=0;

while (deleted_number~=delete)
    random_1=randi([1,A_size(2)],1,1);
    random_2=randi([1,A_size(3)],1,1);
    p=0;
    for nn=1:deleted_number
        if ([random_1,random_2]==deleted_before(nn,:))
            p=1;
        end
    end
    if (p==0)
        A(:,random_1,random_2)=0;
        deleted_number=deleted_number+1;
        deleted_before(deleted_number,:)=[random_1,random_2];
    end      
end
A


سه خط اول برنامه که برای عدم تداخل اطلاعات قبلی موجود در نرم افزار متلب است . شما این سه خط یادت نره خیلی مهمه .
ماتریس A یک ماتریس کوچیکه که نتایج رو روی اون تست کردیم . delete تعداد ستون هایی (یا حالا هر اسمی که روش میگذارید) است که باید تبدیل به صفر بشه . 
ماتریس  deleted_before برای اینه که زوج اعداد تصادفی  random_1 و  random_2 که تولید شدن رو ذخیره کنیم که بعدا چک کنیم که تکرار نشده باشن .
حلقه while رو بر اساس  deleted_number می نویسیم که  deleted_number تعداد ستون هایی است که تاکنون (در حلقه) صفر کرده ایم و وقتی برابر delete شود ، حلقه پایان می یابد .
این هم نتیجه اجرای کد متلب بالا :

کد:
A_size =

     3     2     3


A(:,:,1) =

     0     1
     0     1
     0     1


A(:,:,2) =

     0     0
     0     0
     0     0


A(:,:,3) =

     0     1
     0     1
     0     1

حالا 100 بار هم که اجرا کنید میبینید که تنها 4 ستون صفر میشه (منظورم 100 بار اجرای برنامه بالا است نه اینکه برنامه را به طور 100 بار پیاپی روی یک ماتریس اجرا کنید) . عمدا تعداد ستون ها رو کم و برابر 6 گرفتم که مطمئن بشید .
ممنون ادمین جان ، خیلی زحمت کشیدی . من یک خط رو متوجه نمیشم ،


کد:
[deleted_before(deleted_number,:)=[random_1,random_2;
در این خط برای ماتریس 1*2 به نام deleted_before که قبلا با اعدادی مثل 1 و 2 پر شده بود، میخوایم اعداد تصادفی که باهاش ستون یا بعد سوم ماتریس رو صفر کردیم در ماتریس deleted_before جایگذاری کنیم ولی عدد deleted_number از یک بیشتر میشه ، ماتریس سطریه 1*2 است چطور سطر دوم و سوم و .... براش ساخته میشه ؟ فکر کنم باید به جای عدد deleted_number در اینجا باید همون یک رو بذارید تا اعداد تصادفی در ماتریس 1*2 دخیره بشن . نظرتون چیه ؟ 

5 دقیقه بعد : متوجه شدم ، در حلقه while میاید سطرهای 1 تا جایی که اضافه شده رو چک میکنه ولی برام جا نمیفته چطور ماتریسی که 1*2 تعریف شده سطر بهش اضافه میشه ؟
  
نقل قول:5 دقیقه بعد : متوجه شدم ، در حلقه while میاید سطرهای 1 تا جایی که اضافه شده رو چک میکنه ولی برام جا نمیفته چطور ماتریسی که 1*2 تعریف شده سطر بهش اضافه میشه ؟ 

وقتی قصد داریم که یک ردیف جدید به ماتریسمون اضافه کنیم ، تنها کافیه که مثلا اگر 10 تا ردیف داره ، کد بنویسیم که مقدارهای ردیف 11 ام این ماتریس را برابر یک سری عدد قرار بدهد . نرم افزار متلب به طور خودکار متوجه می شود که قصد داریم اندازه ماتریس را بزرگ کنیم و بنابراین ابتدا اندازه آن را بزرگ کرده و سپس مقادیر ذکر شده را در آن ردیف قرار می دهد .
اگر در همین مثال ماتریس با 10 ردیف ، مقادیری برای ردیف 12 ام تعریف کنیم، نرم افزار متلب ، دو ردیف به ماتریس اضافه میکنه (ردیف 11 و ردیف 12) . چون مقادیر ردیف 12 مشخص شده ، آنها را در ردیف 12 قرار می دهد ولی چون برای ردیف 11 هیچ چیز تعریف نشده ، آنها را برابر صفر می گیرد . 
deleted_before شامل زوج مقادیر انتخاب تصادفی ستون ها است که در روند حلقه ، به تعداد ردیف های آن اضافه می شود و deleted_number تعداد ستون های صفر شده است که تنها یک عدد اسکالر می باشد و هر بار یک واحد به آن افزوده می شود .