6.4 Yhtälön ratkaisua

Yhteenveto

Tässä kappaleessa ratkaisemme yhtälöitä muuttelemalla esimerkkiohjelmien koodia. Yhtälön ratkaisu perustuu tietokoneen kykyyn laskea nopeasti yhtälön vasemman ja oikean puolen arvoja. Kun yhtälön vasemman puolen arvo on sama kuin oikean puolen arvo, niin olemme löytäneet yhtälön ratkaisun. Ensimmäisessä esimerkissä löydämme itse ratkaisun katsomalla tulostetta. Toisessa esimerkissä ohjelmaan on lisätty if-lause, joka tarkistaa milloin yhtälön vasen ja oikea puoli ovat samat.



Ohjelma, joka tulostaa yhtälön 4x + 4 = 3x + 16 vasemman ja oikean puolen arvot, on seuraava. Etsi tulosteesta yhtälön ratkaisu.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta täyttöväriksi eli tekstin väriksi musta.
  3. Aseta tekstin kooksi 20.
  4. Aseta ikkunan taustaväriksi valkoinen.
  5. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -10. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 10. Kasvata muuttujaa x yhdellä).
    1. Määrittele kokonaislukumuuttuja y1 ja sijoita siihen laskutoimituksen 4*x+4 arvo.
    2. Määrittele kokonaislukumuuttuja y2 ja sijoita siihen laskutoimituksen 2*x+16 arvo.
    3. Tulosta muuttujat x ja y1 paikkaan (10,250+x*20). Kun x kasvaa, niin tulostus menee alaspäin.
    4. Tulosta muuttujat x ja y2 paikkaan (210,250+x*20). Kun x kasvaa, niin tulostus menee alaspäin.

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup () {
size(400,500); // Ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
}
void draw() {
for (int x = -10; x <= 10; x++) {
int y1 = 4*x+4; // Laske yhtälön vasen puoli
int y2 = 2*x+16; // Laske yhtälön oikea puoli
text("f("+x+") = "+y1,10,250+x*20); // Tulosta vasen puoli
text("f("+x+") = "+y2,210,250+x*20); // Tulosta oikea puoli
}
}


Ohjelma, joka etsii yhtälön 4x+4 = 2x+16 ratkaisun on seuraava.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta täyttöväriksi eli tekstin väriksi musta.
  3. Aseta tekstin kooksi 20.
  4. Aseta ikkunan taustaväriksi valkoinen.
  5. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -10. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 10. Kasvata muuttujaa x yhdellä).
    1. Määrittele kokonaislukumuuttuja y1 ja sijoita siihen laskutoimituksen 4*x+4 arvo.
    2. Määrittele kokonaislukumuuttuja y2 ja sijoita siihen laskutoimituksen 2*x+16 arvo.
    3. Jos muuttuja y1 on yhtä suuri kuin y2, niin silloin tulosta muuttujan x arvo paikkaan (20,50).

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup () {
size(200,150); // Ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
}
void draw() {
for (int x = -10; x <= 10; x++) {
int y1 = 4*x+4; // Laske yhtälön vasen puoli
int y2 = 2*x+16; // Laske yhtälön oikea puoli
if (y1 == y2) {
text("x = "+x,20,50);
}
}
}

Yhtälöllä kokonaislukuratkaisu

Haluamme ratkaista yhtälön 3x + 2 = x + 10. Kuinka yhtälö voitaisiin ratkaista tietokoneen avulla? Koska for-silmukan avulla voimme tehdä nopeasti laskutoimituksia, niin teemme silmukan -10:stä 10:een ja samalla laskemme yhtälön vasemman puolen 3x+2 ja oikean puolen x + 10 arvoja erikseen. Tehdään seuraava ohjelma.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 600 px vaakaan ja 700 px pystyyn.
  2. Aseta täyttöväriksi eli tekstin väriksi musta.
  3. Aseta tekstin kooksi 20.
  4. Aseta ikkunan taustaväriksi valkoinen.
  5. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -10. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 10. Kasvata muuttujaa x yhdellä).
    1. Määrittele kokonaislukumuuttuja y1 ja sijoita siihen laskutoimituksen 3*x+2 arvo.
    2. Määrittele kokonaislukumuuttuja y2 ja sijoita siihen laskutoimituksen x+10 arvo.
    3. Tulosta muuttujat x ja y1 paikkaan (10,330+x*30). Kun x kasvaa, niin tulostus menee alaspäin.
    4. Tulosta muuttujat x ja y2 paikkaan (310,330+x*30). Kun x kasvaa, niin tulostus menee alaspäin.

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup () {
size(600,700); // Ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
}

void draw() {
for (int x = -10; x <= 10; x++) {
int y1 = 3*x+2; // Laske yhtälön vasen puoli
int y2 = x+10; // Laske yhtälön oikea puoli
text("f("+x+") = "+y1,10,330+x*30); // Tulosta vasen puoli
text("f("+x+") = "+y2,310,330+x*30); // Tulosta oikea puoli
}
}


Ohjelman suoritus näyttää tältä



Milloin vasen puoli on yhtä suuri kuin oikea puoli? Vertaa laskettuja arvoja. Kun x = 4, niin tällöin yhtälön oikea ja vasen puoli ovat samat. Tämä on myös yhtälön ratkaisu. Tietokone osaa löytää yhtälön ratkaisun yksinkertaisesti laskemalla tarpeeksi paljon lausekkeita. If-lauseella voisimme tutkia, milloin yhtälön vasen ja oikea puoli ovat yhtä suuret. Muutetaan koodia.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 500 px vaakaan ja 200 px pystyyn.
  2. Aseta täyttöväriksi eli tekstin väriksi musta.
  3. Aseta tekstin kooksi 20.
  4. Aseta ikkunan taustaväriksi valkoinen.
  5. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -10. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 10. Kasvata muuttujaa x yhdellä).
    1. Määrittele kokonaislukumuuttuja y1 ja sijoita siihen laskutoimituksen 3*x+2 arvo.
    2. Määrittele kokonaislukumuuttuja y2 ja sijoita siihen laskutoimituksen x+10 arvo.
    3. Jos muuttuja y1 on yhtä suuri kuin y2, niin silloin tulosta muuttujan x arvo paikkaan (20,100).

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup () {
size(500,200); // Ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko
background(255); // Valkea taustaväri
}

void draw() {
for (int x = -10; x <= 10; x++) {
int y1 = 3*x+2; // Yhtälön vasen puoli
int y2 = x+10; // Yhtälön oikea puoli
if (y1 == y2) {
text("Yhtälön 3x+2=x+10 ratkaisu on x = "+x,20,100);
}
}
}


Nyt ohjelma ilmoittaa yhtälön ratkaisun.





Kun muutat yhtälöä ja jos mitään ei tulostu, niin syynä voi olla

  • Yhtälön ratkaisu ei ole välillä [-10, 10]. Kasvata tällöin laskuria kirjoittamalla esimerkiksi
    for (int x = -100; x <= 100; x++)
  • Yhtälöllä on desimaaliratkaisu. Katso esimerkki siitä tämän sivun lopussa.

Simulaatio: Yhtälön ratkaisun etsiminen kokeilemalla

Entä jos haluaisimme etsiä yhtälön ratkaisun kokeilemalla isommalla lukuvälillä. Ongelmaksi voi muodostua se, että luvut eivät mahdu enää ruudulle yhtä aikaa. Sen voi kiertää siten, että luomme simulaation, jossa liukupalkilla muutamme x:n arvoa ja ohjelma laskee yhtälön vasemman ja oikean puolen arvon. Teemme seuraavan ohjelman.

SANALLINEN ALGORITMI
  1. Määrittele globaali kokonaislukumuuttuja a ja anna sille alkuarvo 200.
  2. Aseta ikkunan kooksi 400 px vaakaan ja 300 px pystyyn.
  3. Aseta tekstin kooksi 30.
  4. Aseta ikkunan taustaväriksi valkoinen.
  5. Aseta täyttöväriksi keltainen.
  6. Piirrä keltainen suorakulmio, jonka nurkkapiste on (0,0), leveys 400 ja korkeus 50.
  7. Aseta täyttöväriksi punainen.
  8. Piirrä punainen neliö, jonka nurkkapiste on (a,0), leveys 50 ja korkeus 50. Muuttamalla a:n arvoa, saadaan neliö liikkumaan vaakasuunnassa.
  9. Määrittele kokonaislukumuuttuja x1 ja sijoita siihen hiiren vaakasuuntaisen koordinaatin arvo.
  10. Määrittele kokonaislukumuuttuja y1 ja sijoita siihen hiiren pystysuuntaisen koordinaatin arvo.
  11. Jos hiiren painike on pohjassa, niin
  12. Jos (y1 on suurempi kuin 0) JA (y1 on pienempi kuin 50), niin
  13. Jos (x1 on suurempi kuin muuttuja a) JA (a on pienempi kuin 350), niin silloin kasvata muuttujan a arvoa yhdellä. Tällöin punainen neliö liikkuu oikealle.
  14. Jos (x1 on pienempi kuin muuttuja a) JA (a on suurempi kuin 0), niin silloin pienennä muuttujan a arvoa yhdellä. Tällöin punainen neliö liikkuu vasemmalle.
  15. Aseta täyttöväriksi musta.
  16. Määrittele kokonaislukumuuttuja x. Muuta muuttujan a arvo väliltä [0,350] välille [-20,20]. Sijoita tämä uusi muutettu arvo muuttujalle x.
  17. Määrittele kokonaislukumuuttuja yv ja sijoita siihen laskutoimituksen 3*x+2 tulos.
  18. Määrittele kokonaislukumuuttuja yo ja sijoita siihen laskutoimituksen x+10 tulos.
  19. Tulosta tarkasteltava yhtälö eli teksti: "3x+2=x+10" paikkaan (10,100).
  20. Tulosta muuttujien x ja yv arvot paikkaan (10,150).
  21. Tulosta muuttujien x ja yo avot paikkaan (10,200).

// Ohjelman tehnyt e-Oppi Oy, 30.9.2017
int a = 200; // Laskurin alkuarvo (palkille)
void setup () {
size(400,300); // ikkunan koko
textSize(30); // Tekstin koko 30
}
void draw() {
background(255); // Tyhjennä tausta
fill(255,255,0); // Keltainen täyttöväri
rect(0,0,400,50); // Piirrä keltainen suorakulmio
fill(255,0,0); // Punainen täyttöväri
rect(a,0,50,50); // Piirrä punainen neliä
int x1 = mouseX; // Selvitä hiiren vaakakoordinaatti
int y1 = mouseY; // selvitä hiiren pystykoordinaatti
if (mousePressed == true) {
if ((y1 > 0) && (y1 < 50)) {
if ((x1 > a) && (a < 350)) { // Jos hiiri on oikealla puolen
a++; // niin kasvata laskuria
}
if ((x1 < a) && (a >0)){ // Jos hiiri on vasemmalla puolen
a--; // niin pienennä laskuria
}
}
}
fill(0); // Musta tekstin väri
int x = round(map(a,0,350,-20,20)); // skaalaa arvot välille [-20,20]
int yv = 3*x+2;
int yo = x+10;
text("3x + 2 = x + 10",10,100);
text("f("+x+")= "+yv,10,150);
text("f("+x+")= "+yo,10,200);
}


Kun katsot koodia, niin sinun tarvitsee muuttaa vain kolmea lihavoitua riviä, jos haluat tutkia muiden yhtälöiden ratkaisuja. Kun suoritat ohjelman, niin ohjelman suoritus näyttää tältä.



Ohjelma toimii yksinkertaisesti. Kun pidät hiiren painiketta pohjassa keltaisella alueella, niin punainen neliö tulee kohti hiiren vaakasuuntaista paikkaa. Punaisen neliön liikkuminen loppuu, kun punaisen neliön vasen reuna saavuttaa hiiren vaakasuuntaisen paikan. Tässä neliön paikka vaakasuunnassa on skaalattu map()-funktiolla välille [-20,20]. Liikuta palkkia, kunnes yhtälön vasenpuoli on sama kuin yhtälön oikea puoli. Olet löytänyt yhtälön ratkaisun kokeilemalla.

Simulaatio-ohjelman toimintaperiaate on selostettu tarkemmin kappaleessa 8.3. Sinun ei tarvitse osata tehdä simulaatio-ohjelmaa itse alusta loppuun, sinun tarvitsee ainoastaan osata käyttää valmiita simulaatioita. Tässä esimerkissä muuta lihavoidut kohdat, jos tutkit jotain toista yhtälöä.

Yhtälöllä desimaalilukuratkaisu

Edellä kuvattu ratkaisutapa ei toimi, jos yhtälön ratkaisuna on desimaaliluku. Silmukka luvusta -10 lukuun 10 yhden askeleen välein ei anna mitään ratkaisua, jos ratkaisu sattuu kokonaislukujen väliin. Kokeile ratkaista esimerkiksi yhtälö x + 4 = 5x + 2. Ratkaisua ei löydy ja ohjelma ei tulosta mitään.

Jos haluamme ratkaista yhtälön, jossa on desimaalilukuratkaisu, niin joudumme hieman muokkaamaan edellistä esimerkkiä. Aluksi meidän pitää päättää, kuinka monta desimaalia haluamme ratkaisuumme. Jos meille riittää yhden desimaalin ratkaisu, niin silloin voimme kasvattaa for silmukan koko luvusta -100 lukuun 100. Lisäksi emme yritä löytää täysin samaa ratkaisua vaan laskemme yhtälön oikean ja vasemman puolen erotuksen ja määritämme kokeilemalla rajan, milloin olemme tarpeeksi lähellä yhtälön ratkaisua. Tehdään seuraava ohjelma ja ratkaistaan yhtälö.

SANALLINEN ALGORITMI
  1. Määrittele globaali kokonaislukumuuttuja a ja aseta sille alkuarvo 0.
  2. Aseta ikkunan kooksi 500 px vaakaan ja 200 px pystyyn.
  3. Aseta täyttöväriksi eli tekstin väriksi musta.
  4. Aseta tekstin kooksi 20.
  5. Aseta ikkunan taustaväriksi valkoinen.
  6. Aseta asetus, että void draw()-lohko suoritetaan vain kerran.
  7. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -100. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 100. Kasvata muuttujaa yhdellä).
  8. Määrittele desimaalilukumuuttuja y1 ja sijoita siihen laskutoimituksen (x/10.0)+4 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  9. Määrittele desimaalilukumuuttuja y2 ja sijoita siihen laskutoimituksen 5*(x/10.0)+2 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  10. Jos y1:n y2:n erotuksen itseisarvo on pienempi tai yhtä suuri kuin 0.4 (joka on raja-arvo, jota voit muuttaa), niin silloin kasvata laskuria yhdellä ja tulosta löydetyt ratkaisut allekkain laskurin avulla.
  11. Jos muuttujan a arvo on 0 (eli laskuri ei ole kasvanut), niin silloin tulosta kommentti: "En löytänyt ratkaisua. Kasvata raja-arvoa" paikkaan (20,40).

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
int a = 0;
void setup () {
size(500,200); // ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
noLoop(); // Toistetaan vain kerran
}

void draw() {
for (int x = -100; x <= 100; x++) {
float y1 = (x/10.0)+4; // Yhtälön vasen puoli
float y2 = 5*(x/10.0)+2; // Yhtälön oikea puoli
if ((abs(y1 - y2) <= 0.4)) {
a++;
text("Yhtälön x+4=5x+2 ratkaisu on x = "+(x/10.0),20,20+a*20);
}
}
if (a == 0) {
text("En löytänyt ratkaisua. Kasvata raja-arvoa!",20,40);
}
}


Ohjelmassa on lihavoitu ne kohdat, joita sinun tarvitsee muuttaa, jos tutkit muiden yhtälöiden ratkaisua.

Koska for-silmukka on 10-kertainen edelliseen nähden, niin vastaavasti kaikki x:t laskukaavoissa pitää jakaa 10:llä. Nyt voimme käydä kaikki luvut läpi yhden desimaalin tarkkuudella. Tämän takia, joudumme muuttamaan kokonaislukumuuttujat (int) desimaalilukumuuttujiksi (float). Olen etsinyt kokeilemalla rajan, milloin ohjelma löytää yhden ratkaisun. Katso lauseketta: if ((abs(y1 - y2) <= 0.4)), se tarkoittaa samaa kuin että jos itseisarvo yhtälön vasemman puolen arvo vähennettynä oikean puolen arvosta on pienempi tai yhtä suuri kuin 0.4, silloin niin tulosta yhtälön ratkaisu. Uutena Processing-ohjelman komentona esiteltiin funktio: abs(luku); joka tarkoittaa syötetyn luvun itseisarvoa.

Nyt ohjelma tulostaa seuraavaa.



Saman voi havaita, jos laskee funktioiden arvoja taulukkoon.



Raja-arvolla 0.4 tuli vielä yksi ratkaisu. Jos raja-arvo eli lukujen erotus on 0.5, niin tähän väliin mahtuu kolme ratkaisua. Mutta, jos raja-arvo eli lukujen erotus on 0.9, niin silloin tulostuu jo viisi ratkaisua. Taulukon mukaan 0.4:llä olisi pitänyt tulostua kolme ratkaisua, mutta johtuen pyöristyksistä kolme ratkaisua tulostuu heti seuraavasta eli esimerkiksi kun raja-arvo eli lukujen erotus on esimerkiksi 0.41, niin tulostuu jo kolme ratkaisua.

Eli jos kirjoitat if-lauseen muotoon: if ((abs(y1-y2) <= 0.5)), niin ohjelma tulostaa kolme ratkaisua allekkain eli 0.4, 0.5 ja 0.6. Siksi ohjelmaan on lisätty laskuri a, joka tulostaa ratkaisut allekkain, jos raja-arvo on liian suuri. Tällöin löytyy useampi ratkaisu tältä väliltä ja tulostus näyttää silloin tältä.



Tämä kertoo, että lukujen erotus on liian suuri ja raja-arvoa on pienennettävä.

Otetaan vielä toinen esimerkki. Haluamme ratkaista yhtälön 6x + 2 = 3x + 4. Katsotaan mikä on tälle yhtälölle sopiva raja-arvo. Lihavoidaan ohjelmaan tehdyt muutokset.

SANALLINEN ALGORITMI
  1. Määrittele globaali kokonaislukumuuttuja a ja aseta sille alkuarvo 0.
  2. Aseta ikkunan kooksi 500 px vaakaan ja 200 px pystyyn.
  3. Aseta täyttöväriksi eli tekstin väriksi musta.
  4. Aseta tekstin kooksi 20.
  5. Aseta ikkunan taustaväriksi valkoinen.
  6. Aseta asetus, että void draw()-lohko suoritetaan vain kerran.
  7. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja x, joka saa alkuarvon -100. Toista niin kauan kun x on pienempi tai yhtä suuri kuin 100. Kasvata muuttujaa yhdellä).
  8. Määrittele desimaalilukumuuttuja y1 ja sijoita siihen laskutoimituksen 6*(x/10.0)+2 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  9. Määrittele desimaalilukumuuttuja y2 ja sijoita siihen laskutoimituksen 3*(x/10.0)+4 tulos. Kun x jaetaan 10:llä, niin tällöin saadaan aikaiseksi yhden desimaalin tarkkuus.
  10. Jos y1:n y2:n erotuksen itseisarvo on pienempi tai yhtä suuri kuin 0.1 (joka on raja-arvo, jota voit muuttaa), niin silloin kasvata laskuria yhdellä ja tulosta löydetyt ratkaisut allekkain laskurin avulla.
  11. Jos muuttujan a arvo on 0 (eli laskuri ei ole kasvanut), niin silloin tulosta kommentti: "En löytänyt ratkaisua. Kasvata raja-arvoa" paikkaan (20,40).

// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
int a = 0;
void setup () {
size(500,200); // ikkunan koko
fill(0); // Musta tekstin väri
textSize(20); // Tekstin koko 20
background(255); // Valkea taustan väri
noLoop(); // Toistetaan vain kerran
}

void draw() {
for (int x = -100; x <= 100; x++) {
float y1 = 6*(x/10.0)+2; // Yhtälön vasen puoli
float y2 = 3*(x/10.0)+4; // Yhtälön oikea puoli
if ((abs(y1 - y2) <= 0.1)) {
a++;
text("Yhtälön 6x+2=3x+4 ratkaisu on x = "+(x/10.0),20,20+a*20);
}
}
if (a == 0) {
text("En löytänyt ratkaisua. Kasvata raja-arvoa!",20,40);
}
}


If-lauseen raja-arvolla 0.2 tulostuu kaksi ratkaisua peräkkäin eli 0.6 ja 0.7, mutta raja-arvolla 0.1 tulostuu vain yksi ratkaisu.



Huomaa, että jos raja-arvo on alle yhden desimaalin eli esimerkiksi 0.09, niin silloin ei tulostu mitään. Tämä tarkoittaa, että lukujen erotus on jo yli annetun raja-arvon. Silloin raja-arvo on liian pieni. Tätä varten ohjelman loppuun on lisätty kommentti: " En löytänyt ratkaisua. Kasvata raja-arvoa!" Jos tämä ei auta, niin yhtälön ratkaisu ei ole tutkittavalla välillä [-10.0,10.0]. Siinä tapauksessa voit kirjoittaa for-silmukan esimerkiksi muotoon: for (int x=-1000; x <= 1000; x++), jolloin tutkittava väli on [-100.0,100.0] eli kymmenkertainen.

Katsotaan vielä taulukkoon laskettuja arvoja.



Tästä nähdään, että kun raja-arvo eli lukujen erotus on 0.1, niin tulostuu yksi ratkaisu. Vastaavasti raja-arvolla 0.2 tulostuu kaksi ratkaisua. Raja-arvolla 0.4 pitäisi tulostua jo kolme ratkaisua, mutta tulostuukin kaksi. Johtuen pyöristyksistä käytännössä raja-arvo on tässä 4.0000001 jne.

Tällä ohjelmalla voi myös ratkaista kokonaislukuratkaisuja. Silloin raja-arvo on nolla.