17 svar
273 visningar
KriAno är nöjd med hjälpen
KriAno 434
Postad: 24 nov 2019 19:54 Redigerad: 24 nov 2019 21:38

Graf

Hej!

Jag undersöker ett problem som har två villkor: Om talet är jämt så ska det divideras med två, och om det är udda så ska det multipliceras med 3 +1 och divideras med 2. Detta ska upprepas för varje tal tills det når 1. Detta leder i sin tur till att varje tal har ett bestämt antal iterationer till 1.  Jag har försökt programmera en graf där man kan se trajektorian för ett tal på en vertikal logaritmisk skala, men jag får inte riktigt till det.  Jag har försökt återskapa den här grafen:

Men mitt försök ser ut såhär:

...och såhär ser min kod ut:

from math import log
from math import pi, floor
import matplotlib.pyplot as plt

value= 100*floor(pi*10**35)

x_list = [0]
y_list = [log(value)]

print(0,log(value))

iterationer = 0

while value > 1:
    if value % 2 == 1:
        value = (((3 * value) + 1)/2)
        iterationer = iterationer + 1
        print(iterationer, log(value), sep=' ')

    elif value % 2 == 0:
        value = (value / 2)
        iterationer = iterationer + 1
        print(iterationer, log(value), sep=' ')

    y_list.append(log(value))
    x_list.append(iterationer)

print(y_list)
print(x_list)

plt.plot(x_list, y_list, 'k.')
plt.plot(x_list, y_list, 'k-')
plt.grid()
plt.show
plt.savefig()

-----------------

Förstår inte varför det blir så fel... 

Hoppas att någon ser vad det är som blir så tokigt! 

Tacksam för hjälp!

Mvh KriAno

Edit: uppdaterade inlägget med value= 100*floor(pi*10**35)

Lindehaven 820 – Lärare
Postad: 24 nov 2019 21:01

Det är lättare att få hjälp om du publicerar din kod istället för en bild av den. Det är lättare för dig om du jobbar med och avslutar en uppgift i taget.

emilg 478
Postad: 24 nov 2019 21:01

Har du provat value = 100*floor(pi*10**35) som det står i bildtexten?

KriAno 434
Postad: 24 nov 2019 21:40
emilg skrev:

Har du provat value = 100*floor(pi*10**35) som det står i bildtexten?

Jag gjorde precis det, ändrade inlägget därefter, men det blir fortfarande inte rätt.

KriAno 434
Postad: 25 nov 2019 14:20

Förstår inte heller hur antalet steg ner till 1, kan skilja sig så. Jag får 296 steg, medan boken säger 529 steg....

Tendo 158
Postad: 25 nov 2019 14:37

Jag misstänker att det kan handla om overflow testa att använda en annan datatyp som kan lagra större tal.

Tendo 158
Postad: 25 nov 2019 14:41

Ursäkta, märkte att python 3 hanterar detta automatiskt. I Python 2 är det dock relevant.

KriAno 434
Postad: 25 nov 2019 16:11
Tendo skrev:

Ursäkta, märkte att python 3 hanterar detta automatiskt. I Python 2 är det dock relevant.

Okej, jag använder Python 3.7.4

Laguna Online 28587
Postad: 26 nov 2019 07:48

Jag tänkte att antalet steg beror på att du inte har 35 korrekta decimaler på pi, utan bara ungefär 15, för att ett flyttal inte har större precision än så. Men det spelar nästan ingen roll alls: om jag tar rätt 35 decimaler (på nån sida på nätet) så blir det också 296 steg. De sista 20 decimalerna i det tal du använder kan man betrakta som slumpmässiga.

Sen skrev jag ut värdet på value i loopen också och såg att det är ett flyttal. Ett heltal / ett heltal blir ett flyttal i Python (version 3). För att få ett heltal får man använda operatorn //. Då blir det 529 steg.

Men problemet med det raka strecket i plotten måste vara något med enbart plottningen (som jag inte har provat), för listorna ser ju helt vettiga ut.

Lindehaven 820 – Lärare
Postad: 26 nov 2019 07:57 Redigerad: 26 nov 2019 08:01

Problemet uppstår på grund av för få gällande siffror på math.pi (som är 3.14159265359). När math.pi multipliceras med 10**35 så blir produkten för låg.

En lösning är att använda 36 gällande siffror på pi, multiplicera med 10**35 och använda heltalsdelen:

from math import log
import matplotlib.pyplot as plt

pi35 = 314159265358979323846264338327950288
value = 100 * pi35

# code, code, code...

Edit: Laguna hann strax före och är på rätt spår.

jek7 35 – Fd. Medlem
Postad: 26 nov 2019 18:09

math.pi är en float som inte har tillräcklig precision för 35 decimaler, så det avrundas till något som blir delbart med 2 alla första stegen (kolla med print hex(value) så ser du).

Sätt value=314159... istället för formeln med math.pi, google har decimalerna.

KriAno 434
Postad: 26 nov 2019 19:17

Tack så mycket för alla svar! 

Men finns det någon vits med att använda floor (value = 100*floor(pi*10**35)) ? Det funkar väl lika bra utan?

Laguna Online 28587
Postad: 26 nov 2019 20:58 Redigerad: 26 nov 2019 20:59
KriAno skrev:

Tack så mycket för alla svar! 

Men finns det någon vits med att använda floor (value = 100*floor(pi*10**35)) ? Det funkar väl lika bra utan?

Utan floor har du ett flyttal, och då blir det bara 296 steg igen.

jek7 har rätt i att det delas med 2 en massa gånger när det blir ett rakt streck. Det är inget fel på plottningen.

KriAno 434
Postad: 26 nov 2019 21:48 Redigerad: 26 nov 2019 21:51
Laguna skrev:
KriAno skrev:

Tack så mycket för alla svar! 

Men finns det någon vits med att använda floor (value = 100*floor(pi*10**35)) ? Det funkar väl lika bra utan?

Utan floor har du ett flyttal, och då blir det bara 296 steg igen.

jek7 har rätt i att det delas med 2 en massa gånger när det blir ett rakt streck. Det är inget fel på plottningen.

Oj ursäkta, råkade skriva fel i min fråga.

Jag undrar vad som är vitsen med floor här:

pi35 = 314159265358979323846264338327950288
value = 100*floor(pi35)

... när det blir precis samma svar utan, alltså när jag skriver såhär:

value = 100*(pi35)

floor() avrundar väl bara neråt, och är väl därför bara användbart vid decimaltal? Förstår i så fall inte varför boken använder det överhuvudtaget...

Lindehaven 820 – Lärare
Postad: 27 nov 2019 01:15

Enligt dokumentationen för floor():

Return the floor of x as a float, the largest integer value less than or equal to x.

Om du använder heltal enligt mitt förslag behöver du inte floor() eftersom heltalet pi35 redan motsvarar floor(pi*10**35). Du behöver inte heller heltalsdivision eftersom value alltid blir ett heltal.

Laguna Online 28587
Postad: 27 nov 2019 08:39

Framgår det av boken hur man skulle få tag i rätt värde på pi? Det vanliga i math.pi (flyttalet) dög ju inte så bra.

KriAno 434
Postad: 27 nov 2019 10:28
Laguna skrev:

Framgår det av boken hur man skulle få tag i rätt värde på pi? Det vanliga i math.pi (flyttalet) dög ju inte så bra.

Nej, tyvärr inte...

Lindehaven 820 – Lärare
Postad: 27 nov 2019 10:36

Närmevärden till pi kan man beräkna i egna program, läsa i böcker eller finna på internet. Så gjorde jag när jag tog fram pi35 = 314159265358979323846264338327950288.

Svara Avbryt
Close