• Trumpiausias atstumas tarp dviejų taškų. Ar žinote, kodėl jis yra toliau tiesioje nei lanku? Atstumo tarp dviejų susikertančių tiesių nustatymas

    01.02.2022

    Lentoje kreida nubrėžęs du taškus, mokytojas siūlo jaunam mokiniui užduotį: nubrėžti trumpiausią kelią tarp abiejų taškų.

    Mokinys, pagalvojęs, stropiai brėžia tarp jų vingiuotą liniją.

    - Tai trumpiausias kelias! – nustebęs mokytojas. - Kas tave to išmokė?

    - Mano tėvas. Jis yra taksi vairuotojas.

    Naivaus moksleivio piešinys, žinoma, anekdotinis, bet ar nenusišypsotumėte, jei jums pasakytų, kad punktyrinis lankas pav. 1 yra trumpiausias kelias nuo Gerosios Vilties kyšulio iki pietinio Australijos galo!

    Dar ryškesnis yra toks teiginys: pavaizduotas Fig. 2 kelionė pirmyn ir atgal iš Japonijos į Panamos kanalą yra trumpesnė nei tiesi linija, nubrėžta tarp jų tame pačiame žemėlapyje!

    Ryžiai. 1. Jūriniame žemėlapyje trumpiausias maršrutas nuo Gerosios Vilties kyšulio iki pietinio Australijos galo pažymėtas ne tiesia linija („loksodromas“), o kreivė („ortodromija“).


    Visa tai atrodo kaip pokštas, bet tuo tarpu prieš jus – neginčijamos tiesos, gerai žinomos kartografams.




    Ryžiai. 2. Atrodo neįtikėtina, kad lenktas kelias, jungiantis Jokohamą jūros žemėlapyje su Panamos kanalu, yra trumpesnis nei tiesi linija, nubrėžta tarp tų pačių taškų


    Norint išsiaiškinti problemą, reikės pasakyti keletą žodžių apie žemėlapius apskritai ir konkrečiai apie jūrlapius. Nupiešti žemės paviršiaus dalis ant popieriaus net iš principo nėra lengva užduotis, nes Žemė yra sfera, ir yra žinoma, kad jokia sferinio paviršiaus dalis negali būti išdėstyta plokštumoje be raukšlių ir lūžių. Nevalingai tenka susitaikyti su neišvengiamais žemėlapių iškraipymais. Buvo išrasta daugybė žemėlapių braižymo būdų, tačiau ne visi žemėlapiai yra be trūkumų: vieni turi vienokius iškraipymus, kiti kitokius, bet žemėlapių be iškraipymų visai nėra.

    Jūreiviai naudoja žemėlapius, sudarytus pagal senojo XVI amžiaus olandų kartografo ir matematiko metodą. Merkatorius. Šis metodas vadinamas Merkatoriaus projekcija. Jūros žemėlapį nesunku atpažinti pagal stačiakampį tinklelį: dienovidiniai joje pavaizduoti kaip lygiagrečių tiesių eilė; platumos apskritimai – taip pat tiesiomis tiesėmis, statmenomis pirmajai (žr. 5 pav.).

    Įsivaizduokite dabar, kad norite rasti trumpiausią kelią iš vieno vandenyno uosto į kitą toje pačioje lygiagretėje. Vandenyne yra visi takai, ir visada galima keliauti trumpiausiu keliu, jei žinai, kaip jis guli. Mūsų atveju natūralu manyti, kad trumpiausias kelias eina išilgai lygiagretės, ant kurios guli abu uostai: juk žemėlapyje tai tiesi, o kas gali būti trumpesnis už tiesią! Bet mes klystame: kelias išilgai paralelės nėra pats trumpiausias.

    Iš tiesų: rutulio paviršiuje trumpiausias atstumas tarp dviejų taškų yra juos jungiančio didžiojo apskritimo lankas. Tačiau lygiagrečių ratas mažas apskritimas. Didelio apskritimo lankas yra mažiau išlenktas nei bet kurio mažo apskritimo, nubrėžto per tuos pačius du taškus, lankas: didesnis spindulys atitinka mažesnį kreivumą. Ištraukite sriegį ant gaublio tarp dviejų mūsų taškų (plg. 3 pav.); įsitikinsite, kad jis visai nelyja lygiagrečiai. Ištemptas siūlas yra neginčijamas trumpiausio kelio rodiklis, o jei jis nesutampa su lygiagrete žemės rutulyje, tai jūros žemėlapyje trumpiausias kelias nėra nurodytas tiesia linija: atminkite, kad ant tokių pavaizduoti lygiagrečių apskritimai. žemėlapį tiesiomis linijomis, bet kokią liniją, kuri nesutampa su tiesia linija , valgykite kreivė .



    Ryžiai. 3. Paprastas būdas rasti tikrai trumpiausią kelią tarp dviejų taškų: tarp šių taškų reikia ištraukti giją ant gaublio


    Po to, kas pasakyta, tampa aišku, kodėl trumpiausias kelias jūros žemėlapyje pavaizduotas ne kaip tiesi, o kaip vingiuota linija.

    Jie sako, kad renkantis Nikolajevo (dabar Oktyabrskaya) geležinkelio kryptį kilo begalė ginčų, kuriuo keliu jį nutiesti. Ginčus užbaigė caro Nikolajaus I įsikišimas, kuris problemą išsprendė tiesiogine prasme: Sankt Peterburgą sujungė su Maskva. Jei tai būtų padaryta Mercator žemėlapyje, būtų buvę gėdinga staigmena: vietoj tiesios kelio kelias būtų buvęs vingiu.

    Tie, kurie nevengia skaičiavimų, gali paprastu paskaičiavimu įsitikinti, kad kelias, kuris mums žemėlapyje atrodo kreivas, iš tiesų yra trumpesnis už tą, kurį esame pasiruošę laikyti tiesiu. Tegul mūsų du uostai yra 60-oje lygiagretėje ir yra atskirti 60° atstumu. (Žinoma, skaičiuojant nesvarbu, ar tokie du uostai iš tikrųjų egzistuoja.)



    Ryžiai. 4. Atstumų tarp rutulio taškų A ir B išilgai lygiagretės lanko ir didžiojo apskritimo lanko apskaičiavimui


    Ant pav. 4 taškas APIE -Žemės rutulio centras, AB - platumos apskritimo, kuriame yra uostai, lankas A ir B; in jos 60°. Platumos apskritimo centras yra taške NUOĮsivaizduokite tai iš centro APIE per tuos pačius uostus nubrėžtas didysis apskritimo lankas: jo spindulys OB = OA = R; jis praeis arti nubrėžto lanko AB, bet nesutampa.

    Apskaičiuokime kiekvieno lanko ilgį. Nuo taškų BET Ir IN guli 60° platumoje, tada spinduliai OA Ir OV susitaikyti su OS(gaublio ašis) 30° kampu. Stačiakampiame trikampyje ASO koja kintamoji srovė (=r), esantis priešais 30° kampą yra lygus pusei hipotenuzės UAB;

    reiškia, r=R/2 Arkos ilgis AB yra viena šeštoji platumos apskritimo ilgio, o kadangi šis apskritimas turi pusę didžiojo apskritimo ilgio (atitinka pusę spindulio), tai mažojo apskritimo lanko ilgis



    Norėdami dabar nustatyti didžiojo apskritimo, nubrėžto tarp tų pačių taškų, lanko ilgį (t. y. trumpiausią kelią tarp jų), turime žinoti kampo dydį. AOW. Akordas AS, atėmus lanką iki 60 ° (mažas apskritimas), yra taisyklingo šešiakampio, įbrėžto į tą patį mažą apskritimą, kraštinė; Štai kodėl AB \u003d r \u003d R / 2

    Tiesios linijos brėžimas od, jungiamasis centras APIEŽemės rutulys su viduriu D akordai AB, gauti statųjį trikampį ODA, kur kampas D- tiesiai:

    DA = 1/2 AB ir OA = R.

    sinAOD=AD: AO=R/4:R=0,25

    Iš čia randame (pagal lenteles):

    =14°28",5

    taigi

    = 28°57".

    Dabar nesunku rasti norimą trumpiausio kelio ilgį kilometrais. Skaičiavimą galima supaprastinti, jei prisiminsime, kad didžiojo Žemės rutulio minutės ilgis yra

    Sužinome, kad kelias palei platumos ratą, pavaizduotas jūros žemėlapyje tiesia linija, yra 3333 km, o takas didžiuoju apskritimu - išilgai kreivės žemėlapyje - 3213 km, tai yra 120 km trumpesnis.

    Apsiginklavę siūlu ir gaubliu po ranka, galite lengvai patikrinti mūsų brėžinių teisingumą ir įsitikinti, kad didžiųjų apskritimų lankai tikrai yra taip, kaip parodyta brėžiniuose. Pavaizduota pav. 1 tarsi „tiesus“ jūros kelias iš Afrikos į Australiją yra 6020 mylių, o „kreivė“ – 5450 mylių, t.y. trumpesnis 570 mylių, arba 1050 km. „Tiesioginis“ oro maršrutas jūrų žemėlapyje iš Londono į Šanchajų kerta Kaspijos jūrą, o išties trumpiausias maršrutas yra į šiaurę nuo Sankt Peterburgo. Aišku, kokį vaidmenį šios problemos atlieka taupant laiką ir degalus.

    Jei burlaivių laivybos epochoje laikas ne visada buvo vertinamas – tada „laikas“ dar nebuvo laikomas „pinigais“, tai atsiradus garo laivams, tenka mokėti už kiekvieną papildomą sunaudotą anglies toną. Štai kodėl mūsų dienomis laivai plaukioja išties trumpiausiu keliu, dažnai naudojant žemėlapius, padarytus ne Merkatoriuje, o vadinamojoje „centrinėje“ projekcijoje: šiuose žemėlapiuose didžiųjų apskritimų lankai vaizduojami kaip tiesios linijos.

    Kodėl tuomet buvę šturmanai naudojo tokius apgaulingus žemėlapius ir rinkosi nepalankius kelius? Klaidinga manyti, kad senais laikais jie nežinojo apie dabar nurodytą jūrų žemėlapių ypatybę. Reikalas paaiškinamas, žinoma, ne tuo, o tuo, kad Mercator metodu braižyti žemėlapiai kartu su nepatogumais jūrininkams turi labai vertingos naudos. Tokiame žemėlapyje, pirma, vaizduojamos atskiros nedidelės žemės paviršiaus dalys be iškraipymų, išsaugant kontūro kampus. Tam neprieštarauja faktas, kad esant atstumui nuo pusiaujo, visi kontūrai pastebimai išsitempia. Aukštose platumose ruožas yra toks reikšmingas, kad jūros žemėlapis įkvepia žmogų, kuris nėra susipažinęs su jo ypatumais, visiškai klaidingai įsivaizduoti tikrąjį žemynų dydį: Grenlandija atrodo tokio pat dydžio kaip Afrika, Aliaska. yra didesnė už Australiją, nors Grenlandija yra 15 kartų mažesnė už Afriką, o Aliaska kartu su Grenlandija yra perpus mažesnė už Australiją. Tačiau jūreivis, gerai susipažinęs su šiomis diagramos ypatybėmis, negali jų apgauti. Jis toleruoja juos, ypač todėl, kad nedideliuose plotuose jūros žemėlapis tiksliai atvaizduoja gamtą (5 pav.).

    Kita vertus, jūrų žemėlapis labai palengvina navigacijos praktikos uždavinių sprendimą. Tai yra vienintelė diagramų rūšis, kurioje nuolatiniu kursu plaukiančio laivo kelias vaizduojamas kaip tiesi linija. Eiti „pastoviu kursu“ reiškia nuolat laikytis vienos krypties, vieno apibrėžto „rumbo“, kitaip tariant, eiti taip, kad visi dienovidiniai būtų kertami vienodu kampu. Bet šis kelias („loksodromas“) gali būti pavaizduotas kaip tiesi linija tik žemėlapyje, kuriame visi dienovidiniai yra tiesios linijos, lygiagrečios viena kitai. Ir kadangi Žemės rutulyje platumos apskritimai kertasi su dienovidiniais stačiu kampu, tai tokiame žemėlapyje platumos apskritimai turėtų būti tiesios, statmenos dienovidinių linijoms. Trumpai tariant, mes tiksliai pasiekiame koordinačių tinklelį, kuris yra būdingas jūros žemėlapio bruožas.




    Ryžiai. 5. Jūrinis arba Mercator Žemės rutulio žemėlapis. Tokiuose žemėlapiuose kontūrų, esančių toli nuo pusiaujo, matmenys yra labai perdėti. Kuris, pavyzdžiui, didesnis: Grenlandija ar Australija? (atsakymas tekstu)


    Jau suprantamas jūreivių polinkis į Mercator žemėlapius. Norėdamas nustatyti kursą, kurio reikia laikytis einant į nurodytą uostą, navigatorius pritaiko liniuotę į galinius tako taškus ir išmatuoja kampą, kurį ji daro su dienovidiniais. Visą laiką laikydamas atviroje jūroje šia kryptimi, navigatorius tiksliai nuves laivą į tikslą. Matote, kad „loksodromas“ – nors ir ne pats trumpiausias ir ne pats ekonomiškiausias, bet tam tikra prasme labai patogus būdas buriuotojui. Norint pasiekti, pavyzdžiui, nuo Gerosios Vilties kyšulio iki pietinio Australijos pakraščio (žr. 1 pav.), visada reikia laikytis to paties kurso S 87°, 50 ". Tuo tarpu norint atplukdyti laivą į tą patį galutinis taškas trumpiausiu keliu (išilgai ""), būtina, kaip matyti iš paveikslo, nuolat keisti laivo kursą: pradėti nuo kurso S 42 °, 50 "ir baigti kursu N 53 °. 50" (šiuo atveju trumpiausias kelias net neįmanomas - jis remiasi į Antarktidos ledo sieną).

    Abu takai – palei „loksodromą“ ir palei „ortodromą“ – sutampa tik tada, kai kelias didžiuoju apskritimu jūros žemėlapyje pavaizduotas kaip tiesia linija: judant pusiauju arba dienovidiniu. Visais kitais atvejais šie keliai skiriasi.

    (Aprašomoji geometrija)
  • CD (CXDX, C2D2) parodyta kaip taškas C5 = D5 A5B5 lygu...
    (Aprašomoji geometrija)
  • Atstumo tarp dviejų lygiagrečių plokštumų nustatymas
    Atstumo tarp dviejų lygiagrečių plokštumų bendrojoje padėtyje nustatymas 01| X patogu jį redukuoti iki atstumo tarp tų pačių dviejų plokštumų, transformuotų į išsikišančių padėtį, nustatymo. Šiuo atveju atstumas tarp plokštumų apibrėžiamas kaip statmenas tarp linijų, ...
    (Aprašomoji geometrija)
  • Atstumo tarp dviejų susikertančių tiesių nustatymas
    Jei norite nustatyti trumpiausią atstumą tarp dviejų susikertančių tiesių, turite du kartus pakeisti projekcinių plokštumų sistemas. Sprendžiant šią problemą, tiesioginis CD (CXDX, C2D2) parodyta kaip taškas C5 = D5(198 pav.). Atstumas nuo šio taško iki projekcijos A5B5 lygu...
    (Aprašomoji geometrija)
  • Kampas tarp dviejų susikertančių tiesių
    Tai kampas tarp dviejų susikertančių tiesių, lygiagrečių duomenims. Taigi ši užduotis yra panaši į ankstesnę. Norėdami tai išspręsti, turite paimti savavališką tašką ir per jį nubrėžti dvi tiesias linijas, lygiagrečias nurodytoms kreivinėms tiesioms linijoms, ir naudojant projekcijų transformacijas, nustatyti norimą kampą....
    (Aprašomosios geometrijos pagrindai. Trumpas kursas ir uždavinių rinkinys.)
  • Atstumo tarp dviejų lygiagrečių tiesių nustatymas
    Problema išspręsta dvigubo projekcinių plokštumų keitimo metodu. Paskutiniame etape viena iš projekcijos plokštumų turi būti statmena vienai iš susikertančių tiesių. Tada trumpiausias atstumas tarp jų nustatomas pagal statmens kitai pasvirimo linijai atkarpos reikšmę (199 pav.).
    (Aprašomoji geometrija)
  • Kelias išilgai punktyrinės linijos paveikslėlyje yra trumpesnis nei kelias išilgai ištisinės linijos. O dabar šiek tiek plačiau apie jūrų kelių pavyzdį:

    Jei plaukiate pastoviu kursu, tada laivo trajektorija žemės paviršiuje bus kreivė, vadinama matematikoje logaritminisspiralė.

    Navigacijoje ši sudėtinga dvigubo kreivio linija vadinama loksodromija, kas graikų kalba reiškia „įstrižas bėgimas“.

    Tačiau trumpiausias atstumas tarp dviejų Žemės rutulio taškų matuojamas išilgai didžiojo apskritimo lanko.

    Didžiojo apskritimo lankas gaunamas kaip rutulio pavidalo žemės paviršiaus susikirtimo su plokštuma, kertanti žemės centrą, pėdsakas.

    Navigacijoje vadinamas didžiojo apskritimo lankas puikus ratas, o tai reiškia „tiesus bėgimas“. Antroji didžiojo apskritimo ypatybė – dienovidinius jis kerta skirtingais kampais (29 pav.).

    Atstumų skirtumas tarp dviejų žemės paviršiaus taškų išilgai loksodromo ir ortodromo praktinės reikšmės turi tik didelėms vandenyno perėjoms.

    Įprastomis sąlygomis šis skirtumas yra nepaisomas ir navigacija vykdoma pastoviu kursu, t.y. iki loksodromo.

    Norėdami išvesti lygtį, imame loksodromijas (30 pav., bet) du taškai BET Ir IN, atstumas tarp jų tiesiog mažas. Nubrėžę dienovidinius ir per juos lygiagretę, gauname elementarų stačiakampį sferinį trikampį ABC.Šiame trikampyje dienovidinio ir lygiagretės susikirtimo sudarytas kampas yra stačias, o kampas PnAB lygus laivo kursui K. Katet AC reiškia dienovidinio lanko atkarpą ir gali būti išreikšta

    kur R - Žemės spindulys, paimtas kaip sfera;

    Δφ – elementarus platumos prieaugis (platumų skirtumas).

    koja SW reiškia lygiagrečią lanko atkarpą

    kur r - lygiagretės spindulys;

    Δλ - elementarus ilgumų skirtumas.

    Iš trikampio OO 1 C tai galima rasti

    Tada galutinėje formoje koja SW galima išreikšti taip:

    Darant prielaidą, kad elementarus sferinis trikampis ABC butui, rasykite

    Po sumažinimo R ir pakeitę elementarius mažus koordinačių žingsnius be galo mažomis, turime

    Mes integruojame gautą išraišką diapazone nuo φ 1, λ 1 iki φ 2, λ 2 tgK reikšmę laikant pastovia verte:

    Dešinėje pusėje turime lentelės integralą. Pakeitę jo reikšmę, gauname rutulio loksodromo lygtį

    Šios lygties analizė leidžia padaryti tokias išvadas:

    0 ir 180 ° kurso metu loksodromas virsta didžiojo apskritimo lanku - dienovidiniu;

    90 ir 270 ° kampu loksodromas sutampa su lygiagrete;

    Kiekvieną lygiagretę loksodromas kerta tik vieną kartą, o kiekvieną dienovidinį – nesuskaičiuojamą skaičių kartų. tie. spirale artėdamas prie ašigalio jo nepasiekia.

    Navigacija pastoviu kursu, t. y. palei loksodromą, nors tai nėra trumpiausias atstumas tarp dviejų Žemės taškų, navigatoriui yra didelis patogumas.

    Reikalavimai jūriniam navigaciniam žemėlapiui gali būti suformuluoti remiantis navigacijos palei loksodromą pranašumu ir jo lygties analizės rezultatais taip.

    1. Loksodromas, kertantis dienovidinius pastoviu kampu, turėtų būti pavaizduotas kaip tiesi linija.

    2. Žemėlapių sudarymui naudojama kartografinė projekcija turi būti konformiška, kad joje esantys kursai, posūkiai ir kampai atitiktų jų vertę ant žemės.

    3. Meridianai ir lygiagretės, kaip ir kurso linijos 0, 90, 180° ir 270°, turi būti viena kitai statmenos tiesės.

    Trumpiausias atstumas tarp dviejų nurodytų Žemės paviršiaus taškų, imamas kaip sfera, yra mažesnis iš didžiojo apskritimo lankų, einančių per šiuos taškus. Išskyrus laivo, einančio dienovidiniu arba pusiauju, atveju, didysis apskritimas kerta dienovidinius skirtingais kampais. Todėl laivas, einantis tokia kreive, visą laiką turi keisti kursą. Praktiškai patogiau sekti kursą, kuris sudaro pastovų kampą su dienovidiniais ir Merkatoriaus projekcijoje žemėlapyje pavaizduotas tiesia linija – loksodromu. Tačiau dideliais atstumais ortodromo ir loksodromo ilgio skirtumas pasiekia reikšmingą reikšmę. Todėl tokiais atvejais skaičiuojamas ortodromas ir jame pažymimi tarpiniai taškai, tarp kurių jie plaukia palei loksodromą.

    Kartografinę projekciją, atitinkančią minėtus reikalavimus, 1569 m. pasiūlė olandų kartografas Gerardas Crameris (Mercator). Jos kūrėjo garbei projekcija buvo pavadinta Merkatorius.

    O kas nori sužinoti dar įdomesnės informacijos, sužinok daugiau Originalus straipsnis yra svetainėje InfoGlaz.rf Nuoroda į straipsnį, iš kurio padaryta ši kopija -

    DISTANCE, atstumai, žr. 1. Tarpas, skiriantis du taškus, tarpas tarp kažko. Trumpiausias atstumas tarp dviejų tiesės taškų. Gyvena nuo mūsų dviejų kilometrų atstumu. „Komendantas įleido juos artimiausiu atstumu ... Ušakovo aiškinamasis žodynas

    atstumas- daiktavardis, s., vartosena. dažnai Morfologija: (ne) ką? atstumas už ką? atstumas, (žr.) ką? atstumas nei? atstumas, kas? apie atstumą; pl. ką? atstumas, (ne) kas? atstumai, kodėl? atstumai, (žr.) ką? atstumas nei? atstumai... Dmitrijevo žodynas

    atstumas- aš; plg. Erdvė, skirianti du taškus, du objektus ir pan., tarpas tarp kažkieno, nei l. Trumpiausia upė tarp dviejų taškų. R. iš namų į mokyklą. Atsitraukite prie netoliese esančios upės. Metro atstumu ištiestos rankos. Kažką žinoti, kažką jausti. ant… … enciklopedinis žodynas

    atstumas- aš; plg. taip pat žr atstumas a) Tarpas, skiriantis du taškus, du objektus ir pan., tarpas tarp kažkieno, nei l. Trumpiausias atstumas tarp dviejų taškų. Atstumas nuo namų iki mokyklos. Atsitraukite į artimą atstumą / nie ... Daugelio posakių žodynas

    GEOMETRIJOS– matematikos šaka, tirianti įvairių formų (taškų, linijų, kampų, dvimačių ir trimačių objektų) savybes, jų dydį ir santykinę padėtį. Mokymo patogumui geometrija skirstoma į planimetriją ir kietąją geometriją. Į…… Collier enciklopedija

    Navigacija*

    Navigacija- navigacijos skyrius (žr.), baigiant pristatymą, kaip nustatyti laivo vietą jūroje, naudojant kompasą ir žurnalą (žr.). Nustatyti laivo vietą jūroje reiškia žemėlapyje įrašyti tašką, kuriame šiuo metu yra laivas. Enciklopedinis žodynas F.A. Brockhausas ir I.A. Efronas

    COGEN- (Cohen) Hermann (1842 m. 1918) vokiečių filosofas, Marburgo neokantianizmo mokyklos įkūrėjas ir ryškiausias atstovas. Svarbiausi darbai: „Kanto patirties teorija“ (1885), „Kanto etikos pagrindimas“ (1877), „Kanto estetikos pagrindimas“ (1889), „Logika... ...

    Kantas Imanuelis- Kanto gyvenimas ir raštai Immanuelis Kantas gimė Karaliaučiuje (dab. Kaliningradas) Rytų Prūsijoje 1724 m. Jo tėvas buvo balnininkas, o mama – namų šeimininkė, šeši jų vaikai nesulaukė pilnametystės. Kantas visada prisimindavo savo tėvus ...... Vakarų filosofija nuo jos ištakų iki šių dienų

    KANTO KRITINĖ FILOSOFIJA: GEBĖJIMŲ DOKTRINA- (Kanto filosofijos kritika: Facultes doktrinos, 1963), Deleuze'as. Įžangoje apibūdindamas transcendentalinį metodą, Deleuze'as pažymi, kad Kantas filosofiją supranta kaip mokslą apie visų žinių santykį su esminiais tikslais... ... Filosofijos istorija: enciklopedija

    ūkio principas- pagrindinis geometrinės optikos principas (žr. Geometrinė optika). Paprasčiausia F. p. forma yra teiginys, kad šviesos spindulys visada sklinda erdvėje tarp dviejų taškų kelyje, kuriuo jo praėjimo laikas yra mažesnis nei ... Didžioji sovietinė enciklopedija

    Dijkstros algoritmas yra grafinis algoritmas, kurį 1959 metais išrado olandų mokslininkas Edsgeris Dijkstra. Suranda trumpiausius kelius nuo vienos iš grafo viršūnių iki visų kitų. Algoritmas veikia tik grafams be neigiamo svorio briaunų.

    Apsvarstykite algoritmo vykdymą paveikslėlyje pateikto grafiko pavyzdyje.

    Tegul reikalaujama rasti trumpiausius atstumus nuo 1-osios viršūnės iki visų kitų.

    Apskritimai žymi viršūnes, linijos – takus tarp jų (grafiko briaunas). Viršūnių skaičiai nurodyti apskritimuose, virš kraštų – jų „kaina“ – tako ilgis. Prie kiekvienos viršūnės pažymėta raudona etiketė – trumpiausio kelio ilgis į šią viršūnę nuo 1 viršūnės.

    Pirmas žingsnis. Apsvarstykite Dijkstros algoritmo žingsnį mūsų pavyzdyje. Viršūnė 1 turi minimalią etiketę. 2, 3 ir 6 viršūnės yra jos kaimynės.

    Pirmoji 1 viršūnės kaimynė savo ruožtu yra viršūnė 2, nes kelio į ją ilgis yra minimalus. Kelio ilgis į jį per viršūnę 1 yra lygus 1 viršūnės etiketės vertės ir briaunos, einančios nuo 1 iki 2, ilgio sumai, ty 0 + 7 = 7. Tai yra mažesnė už dabartinė 2 viršūnės etiketė, begalybė, todėl naujoji 2 viršūnės etiketė yra 7.

    Panašią operaciją atliekame ir su dar dviem 1-osios viršūnės kaimynais – 3 ir 6.

    Visi 1 mazgo kaimynai yra patikrinti. Dabartinis minimalus atstumas iki 1 smailės yra laikomas galutiniu ir nėra tikslinamas (tai, kad taip tikrai yra, pirmasis įrodė E. Dijkstra). Išbraukite jį iš grafiko, kad pažymėtumėte, jog ši viršūnė buvo aplankyta.

    Antras žingsnis. Algoritmo žingsnis kartojamas. Vėl randame „artimiausią“ iš neaplankytų viršūnių. Tai 2 viršūnė, pažymėta 7.

    Vėl bandome sumažinti pasirinktos viršūnės kaimynų etiketes, bandydami pereiti per jas per 2-ąją viršūnę. 2 viršūnės kaimynės yra 1, 3 ir 4 viršūnės.

    Pirmas (eilės) viršūnės 2 kaimynas yra viršūnė 1. Bet ji jau buvo aplankyta, todėl su 1 viršūne nieko nedarome.

    Kitas 2 viršūnės kaimynas yra 3 viršūnė, nes joje yra mažiausia viršūnių etiketė, pažymėta kaip neaplankyta. Jei eisite į jį per 2, tada tokio kelio ilgis bus lygus 17 (7 + 10 = 17). Tačiau dabartinė trečiosios viršūnės etiketė yra 9, tai yra mažesnė nei 17, todėl etiketė nesikeičia.

    Kitas 2 viršūnės kaimynas yra viršūnė 4. Jei į ją eisite per 2-ąją, tai tokio kelio ilgis bus lygus trumpiausio atstumo iki 2-osios viršūnės ir atstumo tarp 2 ir 4 viršūnių sumai, tai yra , 22 (7 + 15 = 22) . Nuo 22<, устанавливаем метку вершины 4 равной 22.

    Visi 2 viršūnės kaimynai peržiūrėti, atstumą iki jos užfiksuojame ir pažymime kaip aplankytą.

    Trečias žingsnis. Algoritmo žingsnį kartojame pasirinkdami viršūnę 3. Ją „apdorojus“ gauname tokius rezultatus:

    Tolesni žingsniai. Likusioms viršūnėms pakartojame algoritmo žingsnį. Tai bus atitinkamai 6, 4 ir 5 viršūnės.

    Algoritmo vykdymo užbaigimas. Algoritmas baigiasi, kai nebegalima apdoroti viršūnių. Šiame pavyzdyje visos viršūnės yra perbrauktos, tačiau klaidinga manyti, kad taip bus bet kuriame pavyzdyje – kai kurios viršūnės gali likti neperbrauktos, jei jų nepavyksta pasiekti, t.y. jei grafikas yra atjungtas. Algoritmo rezultatas matomas paskutiniame paveikslėlyje: trumpiausias kelias iš viršūnės 1 į 2 yra 7, iki 3 yra 9, iki 4 yra 20, iki 5 yra 20, iki 6 yra 11.

    Algoritmo įgyvendinimas įvairiomis programavimo kalbomis:

    C++

    #include "stdafx.h" #include naudojant vardų erdvę std; const int V=6; // Dijkstra algoritmas void Dijkstra(int GR[V][V], int st) ( int atstumas[V], skaičius, indeksas, i, u, m=st+1; bool aplankyta[V]; for (i= 0 i "< "<> "; cin>>start; Dijkstra(GR, start-1); system("pause>>void"); )

    Paskalis

    programa DijkstraAlgoritm; usescrt; constV=6; inf=100000; tipo vektorius=sveiko skaičiaus masyvas; var pradžia: sveikasis skaičius; const GR: sveikųjų skaičių masyvas=((0, 1, 4, 0, 2, 0), (0, 0, 0, 9, 0, 0), (4, 0, 0, 7, 0, 0), (0, 9, 7, 0, 0, 2), (0, 0, 0, 0, 0, 8), (0, 0, 0, 0, 0, 0)); (Dijkstros algoritmas) procedura Dijkstra(GR: masyvas sveikasis skaičius; st: integer); var skaičius, indeksas, i, u, m, min: sveikasis skaičius; atstumas: vektorius; aplankyta: loginių masyvas; pradžia:=st; jei i:=1 iki V, pradžios atstumas[i]:=inf; aplankytas[i]:=false; galas; atstumas:=0; count:=1 iki V-1 pradėkite min:=inf; už i:=1 iki V do if (nelankyta[i]) ir (atstumas[i]<=min) then begin min:=distance[i]; index:=i; end; u:=index; visited[u]:=true; for i:=1 to V do if (not visited[i]) and (GR<>0) ir (atstumas[u]<>inf) ir (atstumas[u]+GR inf then writeln(m," > ", i," = ", distance[i]) else writeln(m," > ", i," = ", "maršrutas nepasiekiamas"); galas; (pagrindinis programos blokas) begin clrscr; write("Pradžios mazgas >> "); skaityti (pradėti); Dijkstra(GR, pradžia); galas.

    Java

    importuoti java.io.BufferedReader; importuoti java.io.IOException; importuoti java.io.InputStreamReader; importuoti java.io.PrintWriter; importuoti java.util.ArrayList; importuoti java.util.Arrays; importuoti java.util.StringTokenenizer; public class Sprendimas ( private static int INF = Integer.MAX_VALUE / 2; private int n; //viršūnių skaičius digrafe private int m; //lankų skaičius digrafe private ArrayList adj; //gretumų sąrašas privatus ArrayList svoris; //Krašto svoris digrafe naudojamas privatus loginis dydis; //masyvas, skirtas saugoti informaciją apie praleistas ir nepraleistas smailes private int dist; //masyvas atstumui nuo pradinės viršūnės saugoti //protėvių masyvas, reikalingas norint atkurti trumpiausią kelią nuo pradinės viršūnės private int pred; int start; //pradžios viršūnė, nuo kurios atstumas iki visų kitų ieškomas privatus BufferedReader cin; privatus PrintWriter cout; privatus StringTokenizer žetonas; //procedūra Dijkstros algoritmui paleisti nuo pradinės viršūnės private void dejkstra(int s) ( dist[s] = 0; //trumpiausias atstumas iki pradinės viršūnės yra 0 for (int iter = 0; iter< n; ++iter) { int v = -1; int distV = INF; //выбираем вершину, кратчайшее расстояние до которого еще не найдено for (int i = 0; i < n; ++i) { if (used[i]) { continue; } if (distV < dist[i]) { continue; } v = i; distV = dist[i]; } //рассматриваем все дуги, исходящие из найденной вершины for (int i = 0; i < adj[v].size(); ++i) { int u = adj[v].get(i); int weightU = weight[v].get(i); //релаксация вершины if (dist[v] + weightU < dist[u]) { dist[u] = dist[v] + weightU; pred[u] = v; } } //помечаем вершину v просмотренной, до нее найдено кратчайшее расстояние used[v] = true; } } //процедура считывания входных данных с консоли private void readData() throws IOException { cin = new BufferedReader(new InputStreamReader(System.in)); cout = new PrintWriter(System.out); tokenizer = new StringTokenizer(cin.readLine()); n = Integer.parseInt(tokenizer.nextToken()); //считываем количество вершин графа m = Integer.parseInt(tokenizer.nextToken()); //считываем количество ребер графа start = Integer.parseInt(tokenizer.nextToken()) - 1; //инициализируем списка смежности графа размерности n adj = new ArrayList[n]; for (int i = 0; i < n; ++i) { adj[i] = new ArrayList(); ) //sąrašo, kuriame saugomi kraštinių svoriai, inicijavimas weight = new ArrayList[n]; už (int i = 0; i< n; ++i) { weight[i] = new ArrayList(); ) //perskaitykite grafiką, pateiktą pagal briaunų sąrašą (int i = 0; i< m; ++i) { tokenizer = new StringTokenizer(cin.readLine()); int u = Integer.parseInt(tokenizer.nextToken()); int v = Integer.parseInt(tokenizer.nextToken()); int w = Integer.parseInt(tokenizer.nextToken()); u--; v--; adj[u].add(v); weight[u].add(w); } used = new boolean[n]; Arrays.fill(used, false); pred = new int[n]; Arrays.fill(pred, -1); dist = new int[n]; Arrays.fill(dist, INF); } //процедура восстановления кратчайшего пути по массиву предком void printWay(int v) { if (v == -1) { return; } printWay(pred[v]); cout.print((v + 1) + " "); } //процедура вывода данных в консоль private void printData() throws IOException { for (int v = 0; v < n; ++v) { if (dist[v] != INF) { cout.print(dist[v] + " "); } else { cout.print("-1 "); } } cout.println(); for (int v = 0; v < n; ++v) { cout.print((v + 1) + ": "); if (dist[v] != INF) { printWay(v); } cout.println(); } cin.close(); cout.close(); } private void run() throws IOException { readData(); dejkstra(start); printData(); cin.close(); cout.close(); } public static void main(String args) throws IOException { Solution solution = new Solution(); solution.run(); } }

    Kitas variantas:

    Importuoti java.io.*; importuoti java.util.*; public class Dijkstra ( privatus statinis galutinis Graph.Edge GRAPH = ( new Graph.Edge("a", "b", 7), new Graph.Edge("a", "c", 9), new Graph.Edge( "a", "f", 14), naujas Graph.Edge("b", "c", 10), naujas Graph.Edge("b", "d", 15), naujas Graph.Edge("c" ", "d", 11), naujas Graph.Edge("c", "f", 2), naujas Graph.Edge("d", "e", 6), naujas Graph.Edge("e", "f", 9), ); privati ​​statinė galutinė eilutė START = "a"; privati ​​statinė galutinė eilutė END = "e"; vieša statinė galia main (String args) ( grafikas g = naujas grafikas(GRAPH); g.dijkstra (START); g.printPath(END); //g.printAllPaths(); ) ) klasės grafikas (privatus galutinis žemėlapis grafikas; // viršūnių pavadinimų susiejimas su viršūnių objektais, sudarytas iš briaunų rinkinio /** Vienas grafiko kraštas (naudojamas tik Graph konstruktoriaus) */ public static class Edge ( public final String v1, v2; public final int dist; public Edge(String v1, String v2, int dist) ( this.v1 = v1; this.v2 = v2; this.dist = dist; ) ) /** Viena grafiko viršūnė su gretimų viršūnių atvaizdais */ viešoji statinė klasė „Vertex“ padargai Palyginami (viešas galutinis eilutės pavadinimas; viešasis int dist = Sveikasis skaičius.MAX_VALUE; // MAX_VALUE laikoma begalybe vieša viršūnė ankstesnė = null; viešas galutinis žemėlapis kaimynai = naujas HashMap<>(); public Vertex(String name) ( this.name = name; ) private void printPath() ( if (this == this.previous) ( System.out.printf("%s", this.name); ) else if ( this.previous == null) ( System.out.printf("%s(nepasiekta)", this.name); ) else ( this.previous.printPath(); System.out.printf(" -> %s() %d)", this.name, this.dist); ) ) public int palygintiTo(viršūnė kita) ( grąžinti Integer.compare(dist, other.dist); ) ) /** Sukuria grafiką iš briaunų rinkinio * / viešas grafikas (kraštų kraštai) ( grafikas = naujas HashMap<>(kraštai.ilgis); //vienu žingsniu rasite visas (Edge e: briaunos) viršūnes ( if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1)); if (!graph. includeKey(e.v2)) graph.put(e.v2, new Vertex(e.v2)); ) //dar vienas veiksmas, norint nustatyti gretimas viršūnes (Edge e: briaunos) ( graph.get(e.v1). kaimynai.put(grafas.get(e.v2), e.dist); //graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // taip pat darykite tai nenukreiptam grafikui ) ) /** Vykdo dijkstra naudojant nurodytą šaltinio viršūnę */ public void dijkstra(String startName) ( if (!graph.containsKey(startName)) ( System.err.printf("Grafas neveikia yra pradžios viršūnė \"%s\"\n", startName); return; ) galutinis viršūnės šaltinis = graph.get(startName); NavigableSet q = naujas medžio rinkinys<>(); // viršūnių nustatymas (Vertex v: graph.values()) ( v.previous = v == šaltinis ? šaltinis: null; v.dist = v == šaltinis ? 0: Integer.MAX_VALUE; q.add( v); ) dijkstra(q); ) /** Dijkstra algoritmo įgyvendinimas naudojant dvejetainę krūvą. */ private void dijkstra(galutinis NavigableSet q) ( Viršūnė u, v; while (!q.isEmpty()) ( u = q.pollFirst(); // viršūnė su trumpiausiu atstumu (pirma iteracija grąžins šaltinį) if (u.dist == Integer.MAX_VALUE) pertrauka; // galime nekreipti dėmesio į u (ir visas kitas likusias viršūnes), nes jos nepasiekiamos //pažiūrėkite atstumus iki kiekvieno kaimyno (Map.Entry a: u.neighbours.entrySet()) ( v = a.getKey(); //šios iteracijos kaimynas final int alternateDist = u.dist + a.getValue(); if (alternateDist< v.dist) { // shorter path to neighbour found q.remove(v); v.dist = alternateDist; v.previous = u; q.add(v); } } } } /** Prints a path from the source to the specified vertex */ public void printPath(String endName) { if (!graph.containsKey(endName)) { System.err.printf("Graph doesn"t contain end vertex \"%s\"\n", endName); return; } graph.get(endName).printPath(); System.out.println(); } /** Prints the path from the source to every vertex (output order is not guaranteed) */ public void printAllPaths() { for (Vertex v: graph.values()) { v.printPath(); System.out.println(); } } }

    C

    #įtraukti #įtraukti #įtraukti //#define BIG_EXAMPLE typedef struct mazgas_t mazgas_t, *heap_t; typedef struktūra kraštas_t kraštas_t; struct edge_t (mazgas_t *nd; /* šio krašto tikslas */ edge_t *sibling;/* atskirai susietam sąrašui */ int len; /* krašto kaina */ ); struct node_t ( kraštas_t *kraštas; /* atskirai susietas briaunų sąrašas */ mazgas_t *per; /* kur ankstesnis mazgas yra trumpiausiu keliu */ double dist; /* atstumas nuo pradinio mazgo */ simbolio pavadinimas; /* the, er , pavadinimas */ int heap_idx /* nuoroda į krūvos padėtį, kad būtų atnaujintas atstumas */ ); /* --- briaunų valdymas --- */ #ifdef BIG_EXAMPLE # apibrėžkite BLOCK_DIZE (1024 * 32 - 1) #else # apibrėžkite BLOCK_SIZE 15 #endif edge_t *krašto_šaknis = 0, *e_next = 0; /* Nesirūpinkite atminties valdymo dalykais, jie yra ne tik esmė. Pretend e_next = malloc(sizeof(edge_t)) */ void add_edge(mazgas_t *a, node_t *b, double d) ( if (e_next == edge_root ) ( kraštas_šaknis = malloc(dydis(krašto_t) * (BLOCK_DIZE + 1)); kraštas_šaknis.sibling = e_next; e_next = kraštas_šaknis + BLOCK_DIZE; ) --e_next; e_next->nd = b; e_next->len =exdt; ->brolis = a->kraštas; a->kraštas = e_kitas; ) void laisvieji_kraštai() (skirta (; krašto_šaknis; kraštas_šaknis = e_kitas) ( e_next = kraštas_šaknis.brolis; laisva(krašto_šaknis); ) ) /* --- prioriteto eilės medžiaga --- */ heap_t *heap; int heap_len; void set_dist(node_t *nd, node_t *via, double d) ( int i, j; /* jau žinojo geresnį kelią */ if (nd->per && d >= nd->dist) return; /* suraskite esamą krūvos įrašą arba sukurkite naują */ nd->dist = d; nd->via = per; i = nd->heap_idx; if (!i) i = ++heap_len; /* upheap */ for (; i > 1 && nd->dist< heap->dist; i = j) (krūva[i] = krūva[j])->krūvos_idx = i; krūva[i] = nd; nd->heap_idx = i; ) node_t * pop_queue() ( node_t *nd, *tmp; int i, j; jei (!heap_len) grąžina 0; /* pašalinkite pagrindinį elementą, patraukite ten esantį elementą ir nuleiskite */ nd = krūva; tmp = krūva; (i = 1; i< heap_len && (j = i * 2) <= heap_len; i = j) { if (j < heap_len && heap[j]->dist > heap->dist) j++; if (heap[j]->dist >= tmp->dist) break; (krūva[i] = krūva[j])->krūvos_idx = i; ) krūva[i] = tmp; tmp->heap_idx = i; grįžti nd; ) /* --- Dijkstra stuff; nepasiekiami mazgai niekada nepateks į eilę --- */ void calc_all(mazgas_t *start) ( node_t *lead; edge_t *e; set_dist(start, start, 0); while ((lead = pop_queue())) for ( e = švino->kraštas; e; e = e->sibling) set_dist(e->nd, lead, lead->dist + e->len); ) void show_path(mazgas_t *nd) ( if (nd-> via == nd) printf("%s", nd->vardas); else if (!nd->via) printf("%s(nepasekama)", nd->name); else ( show_path(nd->) via); printf("-> %s(%g) ", nd->name, nd->dist); ) ) int main(void) ( #ifndef BIG_EXAMPLE int i; # apibrėžkite N_NODES ("f" - " a" + 1) mazgas_t *mazgai = calloc(dydis(mazgo_t), N_mazgai); už (i = 0; i< N_NODES; i++) sprintf(nodes[i].name, "%c", "a" + i); # define E(a, b, c) add_edge(nodes + (a - "a"), nodes + (b - "a"), c) E("a", "b", 7); E("a", "c", 9); E("a", "f", 14); E("b", "c", 10);E("b", "d", 15);E("c", "d", 11); E("c", "f", 2); E("d", "e", 6); E("e", "f", 9); # undef E #else /* BIG_EXAMPLE */ int i, j, c; # define N_NODES 4000 node_t *nodes = calloc(sizeof(node_t), N_NODES); for (i = 0; i < N_NODES; i++) sprintf(nodes[i].name, "%d", i + 1); /* given any pair of nodes, there"s about 50% chance they are not connected; if connected, the cost is randomly chosen between 0 and 49 (inclusive! see output for consequences) */ for (i = 0; i < N_NODES; i++) { for (j = 0; j < N_NODES; j++) { /* majority of runtime is actually spent here */ if (i == j) continue; c = rand() % 100; if (c < 50) continue; add_edge(nodes + i, nodes + j, c - 50); } } #endif heap = calloc(sizeof(heap_t), N_NODES + 1); heap_len = 0; calc_all(nodes); for (i = 0; i < N_NODES; i++) { show_path(nodes + i); putchar("\n"); } #if 0 /* real programmers don"t free memories (they use Fortran) */ free_edges(); free(heap); free(nodes); #endif return 0; }

    PHP

    $ kraštas, "kaina" => $ kraštas); $kaimynai[$kraštas] = masyvas("pabaiga" => $kraštas, "kaina" => $kraštas); ) $viršūnės = masyvas_unikalus($viršūnės); foreach ($viršūnės kaip $viršūnė) ( $dist[$vertex] = INF; $previous[$vertex] = NULL; ) $dist[$source] = 0; $Q = $viršūnės; while (count($Q) > 0) ( // TODO – Raskite greitesnį būdą gauti minimalų $min = INF; foreach ($Q kaip $vertex)( if ($dist[$vertex]< $min) { $min = $dist[$vertex]; $u = $vertex; } } $Q = array_diff($Q, array($u)); if ($dist[$u] == INF or $u == $target) { break; } if (isset($neighbours[$u])) { foreach ($neighbours[$u] as $arr) { $alt = $dist[$u] + $arr["cost"]; if ($alt < $dist[$arr["end"]]) { $dist[$arr["end"]] = $alt; $previous[$arr["end"]] = $u; } } } } $path = array(); $u = $target; while (isset($previous[$u])) { array_unshift($path, $u); $u = $previous[$u]; } array_unshift($path, $u); return $path; } $graph_array = array(array("a", "b", 7), array("a", "c", 9), array("a", "f", 14), array("b", "c", 10), array("b", "d", 15), array("c", "d", 11), array("c", "f", 2), array("d", "e", 6), array("e", "f", 9)); $path = dijkstra($graph_array, "a", "e"); echo "path is: ".implode(", ", $path)."\n";


    Python

    iš kolekcijų importuoti namedtuple, eilę iš pprint importuoti pprint as pp inf = float("inf") Edge = namedtuple("Edge", "pradžia, pabaiga, kaina") class Graph(): def __init__(self, edges): self .edges = briaunos2 = self.vertices = set(sum(( for e in edges2), )) def dijkstra(self, source, dest): patvirtinti šaltinį savyje.viršūnės dist = (viršūnė: inf viršūnei savyje.viršūnės ) previous = (viršūnė: Nėra viršūnės savyje.viršūnėse) dist = 0 q = self.vertices.copy() kaimynai = (viršūnė: set() viršūnei savyje.viršūnėse) pradžiai, pabaigai, savikainai. briaunos: kaimynai.add((pabaiga, kaina)) #pp(kaimynai) o q: u = min(q, raktas=lambda viršūnė: dist) q.remove(u) if dist[u] == inf arba u = = dest: pertrauka v, kaina kaimynuose[u]: alt = dist[u] + kaina, jei alt< dist[v]: # Relax (u,v,a) dist[v] = alt previous[v] = u #pp(previous) s, u = deque(), dest while previous[u]: s.pushleft(u) u = previous[u] s.pushleft(u) return s graph = Graph([("a", "b", 7), ("a", "c", 9), ("a", "f", 14), ("b", "c", 10), ("b", "d", 15), ("c", "d", 11), ("c", "f", 2), ("d", "e", 6), ("e", "f", 9)]) pp(graph.dijkstra("a", "e")) Output: ["a", "c", "d", "e"]

    Panašūs straipsniai