Max Goessens
Max Goessens

Reputation: 83

How to fix this loop, foreach command adds all variables which it shouldn't

I used to have the following code, that worked:

to build-pipeline-32
    ask storage 32
  [ifelse subsidy-port - pipeline-cost-extensible > 0
    [set pipeline 1]
    [set pipeline 0]
  ]
  ask storage 32
  [ifelse pipeline > 0
    [set subsidy-port subsidy-port - pipeline-cost-extensible]
    [set subsidy-port subsidy-port]
  ]
  ask storage 32
  [if pipeline = 1
    [create-link-from port 25]
 ]
end

to build-pipeline-33
    ask storage 33
  [ifelse subsidy-port - pipeline-cost-extensible > 0
    [set pipeline 1]
    [set pipeline 0]
  ]
  ask storage 33
  [ifelse pipeline > 0
    [set subsidy-port subsidy-port - pipeline-cost-extensible]
    [set subsidy-port subsidy-port]
  ]
  ask storage 33
  [if pipeline = 1
    [create-link-from port 25]
  ]
end

Now I tried this to shorten it, because this just took so many code lines:

to build-pipeline
  foreach sort-on [who] storages
  [ifelse subsidy-port - pipeline-cost-extensible > 0
    [set pipeline 1]
    [set pipeline 0]
  ]
  foreach sort-on [who] storages
  [ifelse pipeline > 0
    [set subsidy-port subsidy-port - pipeline-cost-extensible]
    [set subsidy-port subsidy-port]
  ]
  foreach sort-on [who] storages
  [if pipeline = 1
    [create-link-from port 25]
  ]
end

For some reason, it completely messes up the values of the subsidies. The upper part (setting pipeline value) and below part (creating link) do work. How can I fix this?

One other question: for some reason stack overflow makes me use the question help wizard which is super annoying because I cannot just select a piece of coppied code and format it as code in the question (with the {} option). For this question I had to indent 4 spaces manually for each line... Took forever. Cmd+K doesn't work either. Can I disable this question wizard? Thanks!!

Max

Upvotes: 1

Views: 58

Answers (1)

JenB
JenB

Reputation: 17678

The reason that your model deducts 12x the pipeline costs is because it builds 12 pipeline extensions as soon as there is capital available. You don't deduct the cost until the second foreach but you assign whether or not an extension will be built in the first foreach.

I think you want this (it puts the cost change into the same [ ] so will occur before testing the next possible extension):

to build-pipeline
  foreach sort-on [who] storages
  [ ifelse subsidy-port - pipeline-cost-extensible > 0
    [ set pipeline 1
      set subsidy-port subsidy-port - pipeline-cost-extensible
      create-link-from port 25
    [ set pipeline 0
      set subsidy-port subsidy-port  ; has no effect, can be deleted
    ]
  ]
end

Also, if the only purpose of the pipeline variable is to be 1 or 0 to indicate whether an extension is to be built, this is even easier:

to build-pipeline
  foreach sort-on [who] storages
  [ if subsidy-port - pipeline-cost-extensible > 0
    [ set subsidy-port subsidy-port - pipeline-cost-extensible
      create-link-from port 25
  ]
end

In your comments, you indicated that there is a merit order of pipeline extensions. It is almost always bad coding to use who in NetLogo. The variable who is simply the order the storages are created, tying that to merit removes all flexibility. What happens if later you want a different calculation of merit? The who cannot be changed. What you probably want is to assign a variable named merit for each storage and sort on that variable instead.

Upvotes: 1

Related Questions