NetLogo按特定值排序代理列表

时间:2018-01-10 17:39:30

标签: list netlogo

我有一个拥有5000多名农民和几家工厂的模特。有时会建造一个新工厂,此时我希望工厂执行以下操作:

创建一个包含所有农民的清单,然后根据农民与工厂的距离(从低到高)对该清单进行排序。

我尝试用表格

来做这件事
ask factory 1 [ask farmers [set distance-to-factory distance myself]]
ask factory 1 [set a table:group-agents farmers [distance-to-factory]]

但随后生成的代理集不会从低到高排序,反之亦然。此外,我希望工厂能够事后从订购的表(或列表)中询问单个代理商做某事:

在通过远程工厂订购农民之后,我希望工厂能够要求农民从该清单中提供他们的货物(即首先询问最近的农民,但是当没有货物时,第二个最亲密的农民被问及等等。

非常感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

您需要为工厂创建一个代理变量,以存储距离顺序的农民列表。这是一个完整的例子,运行它并检查工厂以说服自己它有效。

LR_IROM1 0x08020000 0x000E0000; load region size_region
{
    ER_IROM1 0x08020000 0x000E0000; load address = execution address
    {
        *.o (RESET, +First)
        *(InRoot$$Sections)
        .ANY (+RO)
    }
    RW_IRAM1 0x20000000 0x00018000    ; RW data
    {
        .ANY (+RW +ZI)
    }
}

LR_IROM2 0x20018000 OVERLAY 0x00006000; load region size_region
{
    my_Rom2 0x20018000 OVERLAY 0x00006000; load address = execution address
    {
        myAlgorithm1.o (+RO)
    }
    my_Ram2 0x2001E000 OVERLAY 0x00002000    ; RW data
    {
        myAlgorithm1.o (+RW +ZI)
    }
}

LR_IROM3 0x20018000 OVERLAY 0x00006000; load region size_region
{
    my_Rom3 0x20018000 OVERLAY 0x00006000; load address = execution address
    {
        myAlgorithm2.o (+RO)
    }
    my_Ram3 0x2001E000 OVERLAY 0x00002000    ; RW data
    {
        myAlgorithm2.o (+RW +ZI)
    }
}

LR_IROM4 0x20018000 OVERLAY 0x00006000; load region size_region
{
    my_Rom4 0x20018000 OVERLAY 0x00006000; load address = execution address
    {
        myAlgorithm3.o (+RO)
    }
    my_Ram4 0x2001E000 OVERLAY 0x00002000    ; RW data
    {
        myAlgorithm3.o (+RW +ZI)
    }
}

查看初始化工厂程序。在breed [factories factory] breed [farmers farmer] factories-own [my-farmers] to setup clear-all create-farmers 100 [ setxy random-xcor random-ycor set color yellow set shape "circle" set size 0.5 ] create-factories 3 [ setxy random-xcor random-ycor set color red set shape "house" set size 2 initialise-factory ] reset-ticks end to initialise-factory set my-farmers sort-on [distance myself] farmers end 上运行的sort-on原语返回agentset。并且list正在计算返回工厂的距离(因为工厂正在进行询问,因此[distance myself] of ...)。因此,列表按myself排序到工厂。

创建列表后,您可以使用列表过程(例如distance原语)来询问特定的农民。

答案 1 :(得分:1)

确实有多家工厂,工厂的距离是最近创建的工厂,但每个工厂的农民列表并没有改变。

我已经在模型的先前版本上使用了探查器扩展,并且由于每个工厂每次(每年一次)询问每个农民是否有货物,因此非常慢:

let closest-farmer (min-one-of farmers with [status = 0] [distance myself])

这就是为什么我想到每个工厂都会创建一个从最近到最远的农民名单,以便工厂可以查看该清单。下面你会找到一个更精细的代码片段,我希望这能帮助你获得更好的形象。

breed [factories factory]
breed [farmers farmer]

globals [
  count-down 
  total-capacity-factories 
  price-goods
]

farmers-own [
  area 
  goods-per-area 
  goods 
  distance-to-factory 
  status
]

factories-own [
  my-farmers 
  goods-delivered 
  capacity
  revenues-this-year
  total-revenues
]

to setup
  clear-all
  create-farmers 1000 [
    setxy random-xcor random-ycor
    set area one-of [10 50 100]
    set goods-per-area one-of [5 10 15]
    set color yellow
    set shape "circle"
    set size 0.5
  ]
  create-factories 20 [
    setxy random-xcor random-ycor
    set color red
    set shape "house"
    set size 2
    initialise-factory
  ]
  set market-demand-goods 250000
  set total-capacity-factories sum [capacity] of factories
  set count-down 11
  reset-ticks
end

to go
  if count-down = 11 [
    change-market-demand
    ask farmers [
      set status 0
      set goods 0
    ]
  ]
  if count-down = 10 [
    ask farmers [
      sow-seeds
    ]
  ]
  if count-down = 5 [
    if market-demand-goods - [capacity] of one-of factories > total-capacity-factories [
      build-factory
    ]
  ]
  if count-down = 2 [
    ask farmers [ 
      harvest-goods
    ]
    ask factories [
      receive-harvested-goods
      sell-goods
    ]
  ]
  set count-down count-down - 1
  if count-down = 0 [
    set count-down 11
  ]
end

to initialise-factory
  set capacity 10000
  ask farmers [
    set distance-to-factory distance myself
  ]
  set my-farmers (sort-on [distance-to-factory] farmers)
end

to change-market-demand
  let chance random 100
  if chance < 33 [
    set market-demand-goods market-demand-goods - 50000
  ]
  if chance >= 33 and chance < 66 [
    set market-demand-goods market-demand-goods + 10000
  ]
  if chance >= 66 [
    set market-demand-goods market-demand-goods + 50000
  ]
  let chance2 random 100
  if chance2 < 50 [
    set price-goods price-goods + 1
  ]
  if chance2 >= 50 [
    set price-goods price-goods - 1
  ]
end

to sow-seeds
  set color brown
end

to build-factory
  loop [
    if total-capacity-factories >= market-demand-goods [stop]
    create-factory 1 [
      setxy random-xcor random-ycor
      set color red
      set shape "house"
      set size 2
      initialise-factory
      set total-capacity-factories (total-capacity-factories + [capacity] of myself
    ]
end

to harvest-goods
  set goods area * goods-per-area
end

to receive-harvested-goods
  let i 0
  loop [
    if goods-delivered >= capacity [stop]
    let closest-farmer-with-goods (item i my-farmers)
    ifelse [status] of closest-farmer-with-goods = 0 [
      set goods-delivered + [goods] of closest-farmer-with-goods
      ask closest-farmer-with-goods [
        set status "goods-delivered"
      ]
    ]
    [set i i + 1]
  ]
end

to sell-goods
  set revenues-this-year goods-delivered * price-goods
  set total-revenues total-revenues + revenues-this-year
end

答案 2 :(得分:0)

@JenB,谢谢你的帮助!我还发现它可以按如下方式完成:

hatch factory 1 [
  ask farmers [set distance-to-factory distance myself]
  set my-farmers (sort-on [distance-to-factory] farmers)
]

然后我从my-farmer列表中设计了以下代码:

let i 0
loop [
  if goods-delivered > capacity [stop]
  let closest-farmer-with-goods (item i my-farmers)
  ifelse [status] of closest-farmer-with-goods = 0 [ (; aka goods are not delivered yet to another factory) 
    set goods-delivered + [goods] of closest-farmer-with-goods
  ]
  [set i i + 1] ; *else*
]

但是这使得模型非常。你知道怎么做这个更简单吗?