Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- global TX_lib_hillclimb_main is lexicon(
- "BoundryFinder", BoundryFinder@,
- "MinGoldSection", MinGoldSection@,
- "GoldenSearch", GoldenSearch@,
- "Squared", Squared@
- ).
- local TXStopper is "[]".
- Function BoundryFinder {
- parameter Data.
- parameter ScoreSystem.
- parameter StepDirection is (-1).
- parameter StepSize is 0.1.
- clearscreen.
- local ScoreList is list().
- local DataList is list().
- ScoreList:add(Data).
- local OrginialStepSize is StepSize.
- local CurrentData is 0.
- local CurrentX is 0.
- local NewScore is 0.
- until ScoreList:length = 3 {
- set CurrentData to ScoreList[ScoreList:length -1]. //newest entry
- set CurrentX to CurrentData[0].
- set CurrentX to CurrentX + StepDirection * StepSize.
- set StepSize to StepSize * 2.
- local DataList is list().
- set NewScore to ScoreSystem(CurrentX).
- DataList:add(CurrentX).
- DataList:add(NewScore).
- ScoreList:add(DataList).
- // newest entry's x
- // x + direction * step
- // step = step *2
- }
- // when is the middle score the best
- local PrintCounter is 0.
- local BreakAttempt is 0.
- until ScoreList[1][1] <= ScoreList[0][1] and ScoreList[1][1] <= ScoreList[2][1] {
- local TempList is list().
- for ListData in ScoreList {
- TempList:add(ListData).
- }
- TempList:remove(0). // removed oldest entry
- local OldScoreList is list(). // makes a list of the old scorelist to compare with the new scorelist
- for ListData in ScoreList {
- OldScoreList:add(ListData).
- }
- set CurrentData to TempList[1]. // newest entry
- set CurrentX to CurrentData[0]. // x value of newest entry
- set CurrentX to CurrentX + StepDirection * StepSize.
- set StepSize to StepSize * 2.
- local DataList is list().
- set NewScore to ScoreSystem(CurrentX).
- DataList:add(CurrentX).
- DataList:add(NewScore).
- TempList:add(DataList).
- set ScoreList to TempList.
- //set PrintCounter to PrintCounter + 1.
- if PrintCounter = 5 {
- print "0: new old".
- print ScoreList[0][1].
- print OldScoreList[0][1].
- print "1: new old".
- print ScoreList[1][1].
- print OldScoreList[1][1].
- print "2: new old".
- print ScoreList[2][1].
- print OldScoreList[2][1].
- set PrintCounter to 0.
- wait 3.
- }
- if (ScoreList[0][1] > OldScoreList[0][1] and ScoreList[1][1] > OldScoreList[1][1] and ScoreList[2][1] > OldScoreList[2][1]) or (ScoreList[0][1]=ScoreList[1][1]=ScoreList[2][1]) {
- if BreakAttempt = 1 {
- HUDTEXT("no improvement in either way breaking", 5, 2, 30, red, false).
- break.
- }
- set BreakAttempt to 1.
- HUDTEXT("no improvement made! switching sign and resetting StepSize.", 5, 2, 30, red, false).
- print "no improvement made! switching sign and resetting StepSize.".
- set StepDirection to StepDirection*-1.
- set StepSize to OrginialStepSize/10.
- set OrginialStepSize to StepSize.
- }
- }
- print "found best decent guess".
- return ScoreList.
- }
- Function MinGoldSection {
- parameter fn. // scoring function
- parameter a. // lower boundry
- parameter b. // upper boundry
- parameter xtol. // stops when dx is this size
- parameter ftol. // stops when dscore is this size
- local golden is 2 / (1 + sqrt(5)).
- local cgolden is 1 - golden.
- local c is golden * a + cgolden * b.
- local d is cgolden * a + golden * b.
- // a---c--d---b
- local fa is fn(a).
- local fb is fn(b).
- local fc is fn(c).
- local fd is fn(d).
- local dx is 0.
- local df is 0.
- local next is 0. // 1 if next update is C, 2 if D
- if fc < fa and fc < fd {
- set dx to d - a.
- set df to min(abs(fd - fc), abs(fa - fc)).
- // relabel D as B, C as D
- set b to d.
- set fb to fd.
- set d to c.
- set fd to fc.
- set next to 1.
- }
- else {
- set dx to b - c.
- set df to min(abs(fc - fd), abs(fb - fd)).
- // relabel C as A, D as C
- set a to c.
- set fa to fc.
- set c to d.
- set fc to fd.
- set next to 2.
- }
- until abs(dx) < xtol or abs(df) < ftol {
- if next = 1 {
- set c to golden * a + cgolden * b.
- set fc to fn(c).
- }
- else {
- set d to cgolden * a + golden * b.
- set fd to fn(d).
- }
- if fc < fa and fc < fd {
- set dx to d - a.
- set df to min(abs(fd - fc), abs(fa - fc)).
- // relabel D as B, C as D
- set b to d.
- set fb to fd.
- set d to c.
- set fd to fc.
- set next to 1.
- }
- else {
- set dx to b - c.
- set df to min(abs(fc - fd), abs(fb - fd)).
- // relabel C as A, D as C
- set a to c.
- set fa to fc.
- set c to d.
- set fc to fd.
- set next to 2.
- }
- }
- // return the argument of the minimal value found so far
- if next = 1 { return d. }
- else { return c. }
- }
- Function GoldenSearch {
- parameter Data.
- parameter ScoreSystem.
- parameter StepDirection is (-1).
- parameter StepSize is 0.001.
- parameter xtol is 1e-10.
- parameter ftol is 1e-10.
- local DecentScoreList is BoundryFinder(Data, ScoreSystem, StepDirection, StepSize).
- local GoodValue is MinGoldSection(ScoreSystem, DecentScoreList[0][0], DecentScoreList[2][0], xtol, ftol).
- return GoodValue.
- }
- // test function, can be any scoring function that favors a low score
- Function Squared {
- parameter input.
- return sqrt(abs(input)).
- }
- //
- Function Score {
- Parameter NodeList.
- Parameter ScoreType.
- Parameter ScoreList.
- Parameter DeltaVCap.
- local ScoreManeuver is node(NodeList[0], NodeList[1], NodeList[2], NodeList[3]).
- add ScoreManeuver.
- wait until hasnode = true.
- local Result is 20^63.
- local ScoreTypesAvailable is list("Circularize", "Inclination", "Apoapsis", "Periapsis", "ApoapsisMatch", "PerApoMatch", "PerPerMatch", "MoonTransfer", "Interplanetary", "FinalCorrection", "Error").
- local i is 0.
- local Override is false.
- until Result <> 20^63 or Override = true {
- set Result to ScoreExecuter(ScoreType, ScoreTypesAvailable[i], ScoreList).
- set i to i + 1.
- if ScoreTypesAvailable[i] = "Error" {
- set Override to true.
- }
- }
- if ScoreManeuver:deltav:mag > DeltaVCap {
- set Result to 2^64.
- print "surpased delta v cap " at (1, 26).
- }
- if ScoreManeuver:eta < 0 {
- set Result to -1*((2^64)/ScoreManeuver:eta).
- print "eta too close " at (1, 26).
- local TimeCopy is BestCandidate[0].
- BestCandidate:remove(0).
- if time:seconds < TimeCopy {
- BestCandidate:insert(0, TimeCopy+30).
- } else {
- BestCandidate:insert(0, time:seconds+30).
- }
- }
- // if sub_orbital dont penalize below atmosphere
- if ship:status <> "sub_orbital" {
- if ship:body:atm:exists = true {
- if ScoreManeuver:orbit:periapsis < ship:body:atm:height {
- set Result to 2^64.
- print "periapsis under atm " at(1,26).
- }
- }
- if ScoreManeuver:orbit:periapsis < 10000 {
- set Result to 2^64.
- print "periapsis too low (highest point of planet is >0 m) " at(1,26).
- }
- if Result < 0 {
- set Result to 2^64.
- print "result under 0 " at(1,26).
- }
- }
- remove ScoreManeuver.
- return Result.
- }
- Function Improve {
- parameter NodeList. // (time:seconds + 30, 0, 0, 23)
- parameter ScoreList. // (kerbin, kerbin)
- parameter ScoreType. // circularization
- parameter Restriction. // "realnormal_prograde"
- // give nodelist ie. (time:seconds + eta:apoapsis, 0, 0, 10)
- // edit per entry
- local RestrictionTypes is list(
- "timeplus", "timemin", "radialin", "radialout", "realnormal", "antinormal", "prograde", "retrograde"
- ).
- local NonRestrictedList is list().
- local RestrictionStepper is 0.
- until RestrictionStepper = 7 {
- if not Restriction:contains(RestrictionTypes[RestrictionStepper]) {
- NonRestrictedList:add(RestrictionTypes[RestrictionStepper]).
- }
- set RestrictionStepper to RestrictionStepper + 1.
- }
- // all wanted variables are now in NonRestrictedList
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement