Soru sorKapasite Uyarısı
zynparslanturk tarafından 6 yıl önce soruldu

Merhaba,
Aşağıdaki gibi bir kod oluşturdum. Burada

  1. talep; taleplerin olduğu matris. 13×1 boyutlu.
  2. L; büyükten küçüğe sıralanmış bazı değerler, 78×1 boyutlu.
  3. B; indislerin belirleneceği ve talep matrisinden bu indislere göre değer çekileceği bir matris.

Algoritmanın şu şekilde işlemesi gerekiyor. Başlangıçta KKK=0; L matrisinin ilk değerine bak. (ilk değer 1.97 ve B matrisinin (13,9) elemanı) B'den 1.97nin indislerini çek. (bir ayarlamadan dolayı 1 fazla gösteriyor. talep matrisinden 12,1 ve 8,1 elemanlarını çekmesi gerekiyor.) Devamında, eğer talep matrisinin 12. ve 8. satır elemanları 90dan küçükse, KKK değeri güncellensin. 90dan büyükse Lnin ikinci değerine geçsin. aynı işlemleri yapsın. Aşağıdaki kodla bu istediğimi elde ettim. Ama eksik noktalar var; Mesela talep matrisinin
8.satır elemanı=17; 12.satır elemanı=32 // toplamları 17+32=49, 90dan küçük olduğu için KKK değeri 49 olarak güncelleniyor. İkinci en büyük değere yani L'nin ikinci satırına geçiyor. yeni indisler belirleniyor.
"""Bu indislere karşılık gelen talep, 49un üzerine eklensin ;
eğer 90dan küçükse; L'nin 3. satır elemanına geçsin
90dan büyükse; 90-49=41 birimlik talebe eklenebilecek başka değerler var mı diye L'nin tüm elemanlarını kontrol etsin.
eğer böyle bir eleman varsa; mesela L'nin 3,4,5,6. satırları 49a eklenince 90ı geçiyor. ama 7. satır 49a eklenince 90ı geçmiyor. O halde KKK güncellensin. Tüm elemanlar için bu şekilde kontrol sağlandıktan sonra; talep matrisinin 8,12,7 için kendileri ve toplamları gösterilsin. Mesela 8,12,7 =>  79 (17+32+30).
Geriye kalan kullanılmamış L değerleri içinde aynı şeyler yapılsın.

KKK=0

for tt=1:78;
T=L(tt,1)
[i,j] = find(B==T);
i=i-1
j=j-1
if talep(i,1)+talep(j,1)<=90
KKK=KKK+talep(i,1)+talep(j,1);
else
KKK=KKK
tt=tt+1
end
end

:S :S

7 Cevap
zynparslanturk tarafından 6 yıl önce cevaplandı

Birçok kere denedim ama olmadı.

hakkans Yönetici tarafından 6 yıl önce cevaplandı

Merhaba,
Öncelikle, vektörlerle çalıştığınız için [i,j]=find(B==T) gibi bir komut kullanmaktansa [ii]=find(B==T) gibi bir komut kullanmanız yeterli olacaktır. Bu değişkenlere vektör değil matris gibi muamele etmek istiyorsanız bile, bu şekilde kullanım doğru olmayacaktır, çünkü i satır indisini, j ise sütun indisini tutmaktadır (j bu durumda her zaman 1 olacaktır, 9 veya 13 değil). İndis değişkenini ii yapmamın nedeni i değişkeninin Matlab'da aynı zamanda karmaşık sayı için kullanılması. Karmaşık sayılar algoritmanıza girdiği takdirde i'yi değişken olarak kullanmak sorunlara yol açabilir, o yüzden kodunuzdaki i değişkenlerini ii ile veya başka bir değişken ismiyle değiştirmenizi öneririm.

ii değişkeni, eğer B==T şartı birden fazla yerde sağlanıyorsa bir vektör olarak dönecektir. Bu vektör ii=[13 9] şeklinde olacaktır. Bu yüzden, kaç tane ii değeri varsa, if şartına geçmeden önce, bu iki elemandan gelen toplam talebi toplamtalep=sum(talep(ii)); komutuyla toplamanız gerekecektir (Bir döngü adımı içinde birkaç değer çıktığında tek tek değil, bunların toplamına if şartı uygulayacağınızı varsayıyorum.).

Bu değişikliklerle beraber, if şartı aşağıdaki gibi olmalı

if toplamtalep<=90

Ama "…mesela L’nin 3,4,5,6. satırları 49a eklenince 90ı geçiyor. ama 7. satır 49a eklenince 90ı geçmiyor" yazmışsınız. KKK=49 iken, 3. satırdaki elemanı 49'a ekleyince 90'ı geçip geçmediğini kontrol etmek için, if şartınızı aşağıdaki gibi güncellemeniz gerekiyor:

 

if KKK+toplamtalep<=90

İlk döngüde KKK=0 olduğu için bu değişikliğin herhangi bir etkisi yok görünebilir; ama sonrak adımlarda KKK'nın üzerine yeni talep eklendiğinde 90'ı geçmemesini istiyorsanız böyle yazmanız gerekiyor.

8,12,7 ve karşılık gelen değerleri indisvektoru ve indisdegerleri gibi iki tane değişken tanımlayarak, her adımda onların içine atabilirsiniz. İsterseniz öncelikle yukarıda yazdıklarımı inceleyin, sonra bu kısım hakkında yardıma ihtiyacınız olursa tekrar yazabilirsiniz.

zynparslanturk tarafından 6 yıl önce cevaplandı

Merhaba, teşekkür ederim.
Öncelikle benim hem i hem j'ye ihtiyacım var çünkü i ve jler her biri başka bir talep noktasını gösteriyor. Benim amacım i ve j noktasını gerekli şartları sağladığında birleştirmek. Yani önce i noktasına i'nin talep matrisindeki karşılığı olan talebi götürüp, daha sonra j noktasına j'nin talebini götürmem gerekiyor. i ile j noktasını birletirmeyi amaçlıyorum.
 
Kodu şu şekilde güncelledim;
KKK=0

for tt=1:78;
T=L(tt,1)
[ii,jj] = find(B==T);
ii=ii-1
jj=jj-1
toplamtalep=sum(talep(ii));
if KKK+talep(ii,1)+talep(jj,1)<=90
KKK=KKK+talep(ii,1)+talep(jj,1);
else
KKK=KKK
indisdeg=[ii,jj]
indistop=KKK
KKK=0
tt=tt+1
end
end
KKK
indisdeg
indistop
 
Şuan daha iyi çalışıyor. Ama yine bazı eksiklikler var; mesela indisdeg değişkeni, sadece en son indisleri gösteriyor. Ben ekrana Rota1=8-12-7 diye yazdırıp, daha sonra Rota2=5-4-12 şeklinde devam ettireceğim. Ayrıca mesela ben 1 ve 8i kullandıysam, bu noktaları iptal etmeliyim. Tekrar hesaba dahil olmamalılar. Bu kısmı nasıl ekleyebilirim?
Teşekkürler!

hakkans Yönetici tarafından 6 yıl önce cevaplandı

Kodunuzdaki jj değeri hep 1'e eşit olacak, kast ettiğim buydu. Yukarıdaki örnek durumdan devam edersek, kodda şu an ii ve jj şu şekilde:  ii=[9 13], jj=[1 1]. ii ve jj 9 ile 13'e denk gelmiyor. ii vektöründe şartı sağlayan elemanların satır numaraları, jj vektöründe ise bu elemanların sütun numaraları yer alıyor. Satır vektörleriyle çalıştığınız için jj hep 1'e eşit. Anladığım kadarıyla sizin 9 ve 13  elemanlarına (bir çıkartılmış halleri tabii) ihtiyacınız var, o yüzden jj indisini kullanırsanız doğru olmuyor (her döngüde talep(jj,1) ile talep vektörünün ilk elemanını almış oluyorsunuz). toplamtalep değişkenini tanımlama nedenim 8 ve 12. indisteki talepleri toplamak. Bu yüzden if şartında KKK+toplamtalep e bakmak yeterli.

indisdeg ve indistop için şu şekilde bütün değerleri tutabilirsiniz.

indisdeg=[indisdeg ii];
 indistop=[indistop KKK];

Kod döngüsü içinde tt=tt+1 yazmanıza da gerek yok, döngü ilerledikçe tt kendisi artacaktır. Bu satır öncesi KKK=0 neden yazdığınızı da anlayamadım. Böyle olduğu takdirde döngü bitince KKK=0 olarak kalacak. Önceki döngülerden gelen KKK'yı da talebe ekleyemeyeceksiniz.

zynparslanturk tarafından 6 yıl önce cevaplandı

Biraz düşüneyim bunları.
Teşekkürler!

zynparslanturk tarafından 6 yıl önce cevaplandı

Merhaba,
"""""Kodunuzdaki jj değeri hep 1’e eşit olacak, kast ettiğim buydu. Yukarıdaki örnek durumdan devam edersek, kodda şu an ii ve jj şu şekilde:  ii=[9 13], jj=[1 1]. ii ve jj 9 ile 13’e denk gelmiyor."""""
Bu kısmı sanırım anlayamadım.
Benim elimde B=13×14'lük bir matris var. (Her bir noktanın her bir nokta ile olan tasarrufu hesaplanmış. L matrisindeki değerler, B'deki değerlerin sort edilmesi ile elde edildi.)
Ayrıca bir de 13×1'lik talep matrisi var. L'deki en yüksek değer B matrisinin hangi hücresinde? (13,9) ===> (13-1=12, 9-1=8.)
o halde talep matrisinden, 8. ve 12. talepleri topla (rota birleştir.) 
jj'ler neden 1,1'de kalıyor?
 
********tt=tt+1 kısmını düzelttim.
********KKK=0 kısmını; 90ı dolduracak tüm talep noktaları alındıktan sonra, mesela 8-12-7 ilk 90ı doldurdu. Bu ilk rota olarak kalsın. KKK=0'lanıp, yeni bir rota açıp, işlemleri (8-12-7) dışındakiler için tekrar etsin istediğim için eklemiştim. Yanlış olmuş sanırım.
 
Not: Kendi kendime öğrenmeye çalıştığım için, fazla bilmiyorum ve hemen idrak edemeyebiliyorum kusura bakmayın.
Teşekkürler.

hakkans Yönetici tarafından 6 yıl önce cevaplandı

Merhaba tekrardan,
Öncelikle bu platformu Matlab öğrenmek ve öğretmek için kurduğumuz için soru sormaktan çekinmeyin.
Ben yukarıda B'nin de bir matris değil vektör olduğunu düşünmüştüm. B eğer bir matrisse siz haklısınız, jj 1 olarak gelmeyecek her zaman. Bu durumda toplamtalep değişkenine gerek yok. if KKK+talep(ii,1)+talep(jj,1)<=90 şartı yeterli gibi görünüyor.
KKK'yı sıfırlama amacınızı da şimdi anladım. Ancak kod bu haliyle 90'ı aşma durumunun ilkiyle karşılaşınca (3. elemanda oluyor demiştiniz mesela ama 7'de olmuyordu) 7. elemana gidemeden KKK sıfırlanmış olacak. KKK'yı bu 1:78 arası giden döngünün en sonunda yapmanız gerekmez mi? Bu sayede tüm değerleri denemiş olup, artık bu rotayı daha da uzatamayacağınızı görmüş olursunuz. KKK=0 ifadesini if tt==78 gibi bir şartın içine koyabilirsiniz. Son cevabınızda bahsettiğiniz üzere tüm kombinasyonları denemek gibi bir isteğiniz varsa, bunun için iç içe iki for döngüsü gerekecektir. İlk for döngüsü rotanın ilk başlangıç noktasını tutacak, ikinci for döngüsü de (şu anda yazılı olan) vektörün tüm elemanlarını gezip bu başlangıç noktasının üzerine rotayı uzatmaya çalışacak. Aşağıdaki linkte iç içe döngülerle ilgili bir örnek bulabilirsiniz:
https://www.tutorialspoint.com/matlab/matlab_nested_loops.htm