avatar_Hattuşa

bir ölçümde en çok tekrarlayanı bulma

Başlatan Hattuşa, 13 Nisan 2015, 20:08:02

Hattuşa

slm ETE hocam;
yıne saçma sapan bir soru ile karşınızdayım ve fikrinize ihtiyacım var.
hocam bir kanaldan farklı zaman aralıklarında 100 - 200 adet adc okuması yapıyoruz. yani okuma adedi programa göre değişiyor. şimdi sormak istediğim bu okunan adc değerlerinden en çok tekrar edeni nasıl bulabilirim. buble short yöntemi ile en küçük adc değerini, en büyük adc değerini ve ortadaki adc değerini bulabiliyoruz.
ANCAK benim istediğim en çok tekrar eden adc değerini nasıl bulabilirim. ;D   ;D   ;D

ete

Aklın yolu birdir derler. Bu gibi durumlarda benzer işlemi manuel olarak nasıl yapacağımı düşünürüm. Sence nasıl yaparız böyle bir şeyi? Bütün okumaları dizi değişkenine yerleştirmek lazım bu birinci şart.
Sonra ilk okuma değerini alıp bunun index numarasını kayıt altına alırım. Bu sayıyı diğerleri ile karşılaştırıp eşit olup olmadığına bakarım eşitlik yakalarsam bir sayacı bir artırırım.karşılaştırma bitince bu değişkenin index nosunu başka bir yere aktarırım zira bir sonraki ile bunuda karşılaştıracağım. Sayac değerinide bir başka yere aktarırım mesela eski index ve eski sayac gibi.
Sonra ikinci okuma değerini alırım yeni index bunun sıra numarası olur. Sayac değerini sıfırlarım ve aynı işi yeniden yaparım. Hepsini taradıktan sonra eskisayac ile yeni sayacı karşılaştırırm hangisi büyük ise o onun index ve sayac değerini eskiindex ve eski sayac adı altında saklarım. Tekrar index ve sayac değerlerini eskilere aktarırbir sonraki değeri alarak aynı işleri yaparım sonuçta elinde sürekli ençok tekrarlanan değerin index ve sayac değeri bulunmuş olur. Bütün işlem bitince eskindex e karşılık gelen okuma değeri en çok tekrarlanan olmuş olur.
Bu dediklerimi programa adapte etmek çok zor değil. Buble sort döngüsünün aynısı kurulacak karşılaştırma farklı olacak. Yer değiştirmede yapılmayacak hepsi bu.
Ete

Hattuşa

ete hocam; inanın benim aklımdan da bu tip bir şey geçiyordu, ama hala çözmüş değilim. benim yapmaya çalıştığım aslında meyer cihazı gibi bir şey, yani rezistivmeter, toprağa bir miktar voltaj verip ölçüm almak. yani arazide 1 er metre aralıklarla çakılan problardan ölçüm almak işlemi, ölçüm almayıda bir buton ile yaptırıyorum. konu ile ilgili paylaşım reklam olmasın ama ilgili siteyi vereyim.
http://www.teknolojiekibi.com/yeni/index.php?topic=5810.msg71267#msg71267

kayıt işlemi şu şekilde;


if kayıt =0 then
            while kayıt =0 :wend   'butona basıldı bırakılmış mı?
if adimbit =1 then
  adım =adım +1
  if adim =20 then yol =yol +1
  adc[adim] =adin 0
  delayus 20
  if adim =200 then adimbit =0 :adim =1  :print at 1,1,"kayit bitti"
  endif
endif


bu şekilde adc[adim] dizini olarak 200 adet adc elde etmiş olduk.

Hattuşa


sizin söylediğiniz ve benim anladığım şöyle bir şeymi hocam?yukarıda ki örnek üzerinden gidersek


hesap:

for x =0 to 199
sayaca =0
   for y =(x +1) to 200
   if adc[x] =adc[y] then sayaca =sayaca +1 :sayacb =sayaca
  next
  next
 
 


ete

Dizi değişkenini 200 olarak tanımladın ise 0-199 arası okuma yaptırman gerekiyor.
IND_ESKI=0:SAY_ESKI=0  
FOR X=0 to 198
  INDEX=X:SAYAC=1 'ALDIĞIMIZ DEĞER EN AZINDA BİR KERE TEKRARLANMIŞ OLDUĞU İÇİN BU DEĞER 1 ALINIYOR

  FOR Y=(X+1) to 199
    IF ADC[X]=ADC[Y] THEN SAYAC=SAYAC+1
  next

  IF SAYAC>SAY_ESKI THEN
    IND_ESKI=INDEX:SAY_ESKI=SAYAC
  ENDIF 

NEXT   
PRINT AT 2,1,"TEKRARLANAN: ",DEC ADC[IND_ESKI]
PRINT AT 3,1,"ADET.............: ",DEC SAY_ESKI
PRINT AT 4,1,"INDEX...........:",DEC IND_ESKI


Ete


Hattuşa

#5
@ETE hocam teşekkür ederim. aşağıdaki şekilde ki gibi simülasyon oluşturdum ve denediğimde doğru çalışıyor, ancak benim anlamadığım 200 adet ölçüm alınca neden for x=0 to 197 diyoruz. o kısım 198 olması gerekmiyormuydu. birde son satırda neden index değerini 0 görüyorum.

Dim AdC[30] As Word
Dim X As Byte
Dim Y As Byte
Dim Ind_eSkI As Byte
Dim SaYac As Byte
Dim SaY_eSkI As Byte
Dim InDeX As Byte
AdC[0] =100
AdC[1] =105
AdC[2] =110
AdC[3] =100
AdC[4] =108
AdC[5] =112
AdC[6] =100
AdC[7] =111
AdC[8] =104
AdC[9] =100
AdC[10] =101
AdC[11] =98
AdC[12] =96
AdC[13] =100
AdC[14] =90
AdC[15] =99
AdC[16] =100
AdC[17] =103
AdC[18] =113
AdC[19] =100
AdC[20] =107
AdC[21] =95
AdC[22] =104
AdC[23] =100
AdC[24] =101
AdC[25] =112
AdC[26] =100
AdC[27] =108
AdC[28] =110
AdC[29] =100
Print Font Frank____6 
Print At 2,2,"TEKRARLANAN:"
Print At 12,2,"ADET:"
Print At 22,2,"INDEX:"
MaIn:
Ind_eSkI=0:SaY_eSkI=0 
For X=0 To 27
  InDeX =X:SaYac=1 'ALDIĞIMIZ DEĞER EN AZINDA BİR KERE TEKRARLANMIŞ OLDUĞU İÇİN BU DEĞER 1 ALINIYOR

  For Y=(X+1) To 28
    If AdC[X]=AdC[Y] Then SaYac =SaYac +1
  Next

  If SaYac>SaY_eSkI Then
    Ind_eSkI =InDeX:SaY_eSkI =SaYac
  EndIf 

Next   
Print At 2,60,Dec AdC[Ind_eSkI]
Print At 12,60,Dec SaY_eSkI
Print At 22,60,Dec Ind_eSkI
Stop

ete

#6
Dediklerimi yanlış anlamışsın.
Dim AdC[200] As Word
şeklinde bir değişken tanımlaması yapmış isen bu 0-199 arasında 200 adet değer demektir.
Bu nedenle döngüler kurulurken.
FOR X=0 to 198  (toplam adedin bir eksiğine kadar yani en baştan toplam adedin bir eksiğine kadar)
FORY=(X+1) to 199 (yani ikinciden toplam adede kadar döngü kuruluyor).
şeklinde kurulur bunu demek istemiştim. Verdiğim örnek de tam bu açıklamaya uygun. 197 rakamını nereden çıkardın bilemiyorum.

Ölçüm değerleri listesine bakarsan en fazla 100 değerini ölçmüş görünürsun.
Peki ilk 100 rakamının index numarası kaç tabiiki "0" sıfır yani. O yüzden aşağıda index numarası olarak 100 görüyorsun.
İlk rakamı 115 ikinciyi 100 yap  bu sefer index numarasını 1 göreceksin. En çok tekrarlanan okuma rakamının ilk index değeri orada gösterilmektedir.

Ete

not: senin örnekte döngüler eksik kurulmuş gözüküyor. Birinci döngü 0- 28 arasında ikinci ise (X+1) ile 29 arasında kurulmalı.


Hattuşa

hocam ne olacak benim bu halim. hep hata hep hata...

ete

Halinde bir şey yok aslında. Biraz dikkatsiz biraz acelecisin o kadar. Programcılıkta hemen her şey mantık çerçevesinde yürür. İlk yapılması gereken mantığı kuvvetlice çalıştırmak. Sonra dikkatlice kodları yazmak ve bir kerede üzerinden geçip kafada test etmek gerekir. AKlına ilk gelen şeyi yazmaman üzerinde düşünüp gerekirse kağıt üzerinde çalışıp işi bitirmelisin. Kod önce kafada biter. Başlayayım gerisi gelir dersen bu şekilde hatalar ortaya çıkması kaçınılmaz oluyor.

Ete

Hattuşa

@ete hocam şu en çok tekrarlayan kısmında en çok tekrarlayan değer bazen 5-3 adc yakın çıkıyor. bunu bu formulle bulurken nasıl tolere edip tekrarlayan değeri buldurabilirim?

ete

#10
Tam olarak ne istediğini anlamadım. Bir birlerine yakın değerleri bir formülle aynı değermiş gibi mi algılamak istiyorsun?
Bunu en çok tekrarlananı bulurken yapmak belkide daha uygun olur. Aklıma şöyle bir şey geldi.

Önce en çok tekrarlayanı buluyoruz ancak bulurken bir aralık veriyoruz aşağıdaki örnekte ilk okunan bir sonraki okunana eşit veya ilk okunan ,sonraki okunanın 3 eksiğinden büyük ve 3 fazlasından küçük ise  bunu eşitmiş gibi kabul et diyoruz.
Burada veridğimiz aralık 3 eksiği ile 3 fazlası. Sen bu 3 rakamlarını 5 yaparsan 5 eksiği ile 5 fazlası aralığınıda kabul eder.

for x=0 to 28
INDEX=X:SAYAC=1 :TEKRAR[X]=1
FOR Y=(X+1) TO 29
  IF ADC[X]=ADC[Y] or (adc[x]>adc[y]-3 and ADC[X]<ADC[Y]+3) THEN
    TEKRAR[X]=TEKRAR[x]+1
  ENDIF 
NEXT Y
NEXT X

Bu şekilde tekrarlanan değerleri sırası ile her okunan adc değeri için bulmuş oluruz. Burada Tekrar[30] şeklinde bir dizi değişkeni daha kullanmış oldum bunu programın başında tanımlaman gerektiğini biliyorsunudur.

Bu aşamadan en çok tekrarlanan elemanı bulmamız gerekiyor onun için ikinci bir döngü daha kuruyoruz,
 INDEX=0:SAYAC=1
FOR X=0 TO 29
    IF TEKRAR[X]>SAYAC THEN
       SAYAC=Tekrar[x]
       INDEX=x
    endIF

Şimdi elimizde ne var ona bakalım.
INDEX değeri (0-29) aralığında bir değer olarak en çok tekrarlanan okuma değerinin index numarasını bize verecektir.
Diyelimki bu değer 10 dur.
O halde en çok tekrarlanan değer ADC[10] değeridir.
Bunuda son döngüden sonra bir satır ilave ederek,
 LCDOUT $FE,$80,"ENCOK=",DEC3 ADC[INDEX],"INDEX=",dec2 INDEX
lcdout $fe,$c0,"tekrar=",dec3 tekrar[index]

şeklinde ekranda görebilirsin.

Ete

Powered by EzPortal