Permalänk
Medlem

Matlab hjälp, while sats

Tja!

Jag är i behov av er hjälp med ett litet problem i matlab.

Jag har en vektor vald=[1;0;0]

Som illustrerar vilket alternativ jag tidigare använt mig av och inte får använda igen.

Vald illustrerar vilken plats i vektorn s=[20;5;10] jag tidigare har valt. Jag får alltså inte välja det första alternativet igen, men hur gör jag detta?

Låt oss säga att jag har ett behov som från början är 32, när ni kommer in i koden så har jag redan valt 20 och mitt behov är alltså nu 32-20=12. Kodsnutten som jag behöver hjälp med ska alltså göra detta:

while behov >= 0
kolla vilket värde som är störst i vektorn s,
kolla så att det inte är valt vald=1 på den platsen,
om det är valt, kolla näst största om det är valt etc
sätt vald=den position vi väljer
behov - valda i s (ex 12-10=2)
loopa tills behovet är <= 0

Jag har försökt att beskriva mitt problem så tydligt som möjligt och hoppas att ni kan hjälpa mig med det. Koden ska fungera för vektorer med varierande storlek exempelvis s=[13 300 21 453 2 20]

Hoppas att någon kan hjälpa mig med denna lilla kodsnutt, tack på förhand!

Permalänk
Medlem

istället för att bara beskriva detta enskilda problem, kan du beskriva vad programmet ska göra så kanske vi kan hjälpa till med den totala lösningen.

Visa signatur

weeeee

Permalänk
Medlem

Vad ska hända om det finns två lika stora värden i s?
I följande kod antar jag att det största värdet är unikt.

while behov >= 0 maxvarde = max((vald==0) .* u) behov = behov - maxvarde vald = vald + (s == maxvarde) end

Observera att jag inte testat något av ovanstående, men du kan göra ungefär på det sättet.

Visa signatur

I'm Winston Wolfe. I solve problems.

Permalänk
Medlem

förlåt mig men jag var dum när jag skrev mitt inlägg, det är det lägsta värdet jag vill få ut, jag råkade vända på alla siffror tyvärr.

Och om jag kör din kod då:
[minvarde,index] = min((vald==0) .* u)
så är minvärde 0 eftersom att man på inte multiplicerar på den raden.
efter jag multiplicerat ser den ut såhär:
[20;0;10]
så jag vill alltså få ut det minsta värdet som inte är noll.
det är alltså värdet tio på index tre jag vill välja men den väljer värdet i mitten, alltså noll.

Löser jag det såhär så får den fel index men rätt värde:
[minvarde,index] = min(nonzeros((vald==0) .* u))
Så jag vill alltså lösa detta på något sätt så att jag får det minsta värdet som inte är noll med rätt index, i detta fall är rätt index 3 men jag får indexet 2. Jag behöver hjälp med hur man kan lösa det.

Angående din fråga vad som ska hända om två lika stora värden på s finns så ska den bara ta en av dem, det spelar ingen roll vilken av den då väljer sålänge den bara väljer en åt gången.

Permalänk
Medlem

skapa en vektor, v, med ones, när du plockar ett tal så sätter du elementet som korresponderar med samma index i v till noll. När du nu söker efter min så använder du values(v~=0) för att plocka fram de värden som du ännu ej använt, alltså kan du använda min( values(v~=0) ) för att finna detta värde. Nästa problem är att finna detta värdes index representerat i v's index.
Men du kan ju alltid använda två utvärden från min så har du indexet, fortfarande i delmängden till values. Men detta index (n) motsvarar ju precis den n:te ettan i v.

values = [8 1 4 2]
v = [1 1 1 1]
values(v>0) = [8 1 4 2]
min([8 1 4 2]) ==> 1, index 2
ind = max(find(v>0, 2)) = max([1 2]) = 2
v(2) = 0 ==> v =[1 0 1 1]

values(v>0) = [8 4 2]
min([8 4 2]) ==> 2, index 3
ind = max(find(v>0, 3)) = max([1 3 4]) = 4
v(4) = 0 ==> v =[1 0 1 0]

osv... har inte testat med matlab eller octave, men mitt huvud säger att detta borde fungera ... med viss modifikation

återigen, vad ska ditt script göra totalt sett?? Det finns säkert en bättre "total-lösning"

Visa signatur

weeeee

Permalänk
Medlem

hmm, jag förstår inte riktigt hur jag ska få detta att fungera för olika storlek på v och values.. Det ska alltså inte vara hårdkodat utan ska kunna innehålla 40 olika index osv.

kom ihåg att m, n, s, d, f, c ska kunna vara av varierande storlek.

men eftersom jag behöver mer hjälp postar jag hela koden.

m = 3; n = 5; s = [ 239 225 184 ] ; d = [ 92 82 83 69 74 ] ; f = [ 589 766 886 ]; c = [ 14 5 6 24 6 9 22 26 5 21 16 11 23 28 24 ]; %1 om öppnad, 0 om inte öppnad oppnade = zeros(m,1); %loop som kollar billigast totalpris for i=1:1:m totKostnad=0; %antal kunder j for j=1:1:n tempJ=c(i,j); totKostnad=totKostnad+tempJ; end; lagstaTotalkostnad(i,1)=(totKostnad+f(i)*1)/s(i) end; %Kolla vilken som har lägst enskild kostnad [lagstKostnad,Index]=min(lagstaTotalkostnad) %Räkna ut total efterfrågan från alla kunder tillsammans totEfterfragan=0; for i=1:1:n totEfterfragan=totEfterfragan+d(i) end %här som jag behöver hjälp med min %whilesats som uppfyller total efterfrågan [lagstKostnad, Index]=min((oppnade==0).*lagstaTotalkostnad)

Jag hoppas att det är kommenterat tillräckligt väl, och bara för att påpeka så är jag inte ute efter den bästa lösningen som kräver minst antal rader för att skriva utan för att lära mig det, så behåll gärna strukturen på koden och ändra den inte totalt utan lägg bara till vad som krävs för att få den att fungera, jag har inte tänkt så mkt på att den ska vara jättekort och optimal utan bara att den ska fungera, resten får jag fundera på sen.

Permalänk

missförstod sry

går det inte göra så att du kopierar din vektor till en ny vektor och sedan varje gång du tar en siffra ur denna nya vektor sparar du bara undan denna i sig själv utan de värde du tog bort?? då behöver du ju inte bry dig om att kolla att de är använt eller tänker jag fel nu?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av fizzyflaskan
missförstod sry

går det inte göra så att du kopierar din vektor till en ny vektor och sedan varje gång du tar en siffra ur denna nya vektor sparar du bara undan denna i sig själv utan de värde du tog bort?? då behöver du ju inte bry dig om att kolla att de är använt eller tänker jag fel nu?

hmm, får jag rätt index då? För det känns som att du då bara får ut rätt värde men att du struntar helt i indexhanteringen. Jag kan dock ha missförstått dig, visa gärna en liten kodsnutt på hur du menade om jag missuppfattade dig.
För meningen med detta är att jag få ut rätt index på de jag har valt. Meningen med hela denna while,min sats som jag behöver hjälp med är att få ut rädd indexhantering på öppnade.

Permalänk
Medlem

Börjar man med att sortera så behöver du aldrig leta efter det lägsta värdet.
Sedan så nollar du de värden du redan använt istället för att spara det i en vektor.

v = sort(u); while behov >= 0 behov = behov - v(1,1) v = v(1,2:length(v)); end

Visa signatur

I'm Winston Wolfe. I solve problems.

Permalänk
Medlem

matti4s, bra idé lägg där till att du kan få ut permutationen från sorteringen direkt från sort så är han hemma (om han vill ha den urspringliga ordningen )

Visa signatur

weeeee

Permalänk
Medlem

bump, tack för er hjälp!