Как не создавать избыток агентов при чтении их характеристик из CSV-файла

У меня есть данные о 100 потребителях-черепахах, которые оценили характеристики ноутбуков. Ноутбуки имеют 2 вида характеристик: размер экрана и время автономной работы. Каждый имеет несколько уровней. Например, срок службы батареи составляет 5 часов, 12 часов, 24 часа, 30 часов. Данные хранятся в файле csv. Для простоты здесь вы видите 2 потребителя.

   size12  size13.5  size14  size15  Battery5  Battery12 Battery24 Battery30 
1  1        *2*         1      3        2         2           *4*       5
2  4        3           3      2        1          1           2        3

Мы получаем доступ к набору данных, чтобы суммировать показатели двух уровней функции. Например, для потребителя 1, что такое:

The sum of rates of screen size of 13.5 + rate of battery life 24

Используя приведенный ниже код, это достигается:

to CalculateSumRates
  ca
  reset-ticks
  file-close-all
  file-open "turtle_details.csv"
  let headings csv:from-row file-read-line
  set screen-headings sublist headings 0 4
  set battery-headings sublist headings 4 length headings

  let screen-to-evaluate 13.5
  let battery-to-evaluate 24

  while [ not file-at-end? ] [
    let data csv:from-row file-read-line
    create-turtles 1 [
      set turtle-screen-list sublist data 0 4
      set turtle-battery-list sublist data 4 length data
      set turtle-screen-eval turtle-screen-rating screen-to-evaluate
      set turtle-bat-eval turtle-battery-rating battery-to-evaluate
      set turtle-sum-eval turtle-screen-eval + turtle-bat-eval
    ]
  ]
  file-close-all

end

to-report turtle-screen-rating [sc]
  let pos position sc screen-headings
  let turt-screen-rate-value item pos turtle-screen-list
  report turt-screen-rate-value
end

to-report turtle-battery-rating [bc]
  let pos position bc battery-headings
  let turt-bat-rate-value item pos turtle-battery-list
  report turt-bat-rate-value
end

Теперь я хочу сделать что-то большее. Мне нужно учитывать временной интервал. Например, через 20 лет, как потребители меняют свои оценки некоторых функций ноутбуков. Чтобы проиллюстрировать больше, потребитель 1, который выразил свой общий рейтинг размера 13,5 и батареи 24, в год 2 (галочки = 2) улучшил свой ноутбук, поэтому теперь мы хотели бы знать:

The sum of rates of screen size of 13.5 + rate of battery life **30**

Сначала я создал свой go следующим образом:

 to setup
      CalculateSumRates
    end


to go
repeat 20 [

   { screen-to-evaluate changes and is no longer 13.5}
   { battery-to-evaluate also changes and is no longer 24}

; ИЗМЕНИТЬ

set turtle-screen-eval turtle-screen-rating screen-to-evaluate
  set turtle-bat-eval turtle-battery-rating battery-to-evaluate
  set turtle-sum-eval turtle-screen-eval + turtle-bat-eval

; ИЗМЕНИТЬ

  tick
]
end

Проблема здесь в том, что каждый раз, когда вызывается CalculateSumRates, он переходит к этой строке:

 create-turtles 1 [

Таким образом, каждый год 100 потребителей создаются с нуля, а мне нужно отслеживать поведение этих 100 потребителей в начале.

Затем я написал 2 функции CalculateSumRates, одну из которых вызвал при настройке. Переименовал функцию и поставил другую в ход. Чтобы не создавать избытка потребителей, я заменил create-turtles 1 [ на ask consumers [, надеясь, что теперь csv снова читается, но читается построчно, когда я говорю спросить потребителей, поэтому я могу найти разные значения из набора данных. Однако он работает странно. Я не знаю, как это изменить, чтобы не создавать новых потребителей и не терять предыдущих?

Добавляя строки в редактирование, я сталкиваюсь с ошибкой, говорящей мне, что я не могу использовать go в контексте наблюдателя; идти только черепаха!! Спасибо,


person user710    schedule 14.07.2017    source источник
comment
Можете ли вы опубликовать код на CalculateSumRate? Кроме того, потребители из года в год одни и те же или разные? То есть совпадают ли потребители в первом наборе данных с потребителями в будущих наборах данных? Как хранятся будущие наборы данных? Просто отдельные файлы CSV?   -  person Bryan Head    schedule 14.07.2017
comment
Спасибо. Потребители одни и те же из года в год. У меня также есть только один набор данных, который будет использоваться каждый год. Набор данных тот же, но каждый год для каждого потребителя будут считываться разные столбцы. Например, в год 1 для потребителя 1 мне нужно знать, каковы показатели размера экрана 13 и батареи 24, но в следующем году мне нужно получить доступ к другому уровню, например размеру экрана 13,5 и батарее 30. Код для 'CalculateSumRate' там. Но эти строки «пусть экран для оценки 13,5 пусть батарея для оценки 24» будут другими с течением времени.   -  person user710    schedule 14.07.2017
comment
Думаю, теперь я понимаю немного лучше. Причина, по которой я предложил вам использовать этот подход в моем примере здесь, где каждая черепаха хранит свои потенциальные значения, заключается в том, что вы можете затем получить доступ к значению этой черепахи для любой комбинации времени работы экрана/батареи. Вы не должны возвращаться к csv вообще - в этом нет необходимости, так как у черепашки есть список рейтингов, которые, что важно, вы можете обновлять по мере необходимости (если они меняют свой экранный рейтинг, например ).   -  person Luke C    schedule 14.07.2017
comment
Огромное спасибо. Я мог представить, что могу получить доступ к любой комбинации с помощью вашего подхода, но у меня были некоторые трудности с этим. Я отредактировал свой вопрос, добавив в качестве правок то, что вызывает проблему.   -  person user710    schedule 14.07.2017
comment
Извините, я только что увидел это после того, как написал ответ - загляните туда и посмотрите, может ли это объяснить ошибку, которую вы получили.   -  person Luke C    schedule 14.07.2017


Ответы (1)


Чтобы привести пример того, что я имел в виду в комментарии выше, ознакомьтесь с этой модифицированной версией установки, которую я предложил здесь.

extensions [ csv ]

globals [ screen-headings battery-headings ]

turtles-own [
  turtle-screen-list
  turtle-battery-list
  turtle-screen-eval
  turtle-bat-eval
  turtle-sum-eval
  turtle-row-number
  ;; New:
  rating-each-year 
]

to setup
  ca
  reset-ticks
  file-close-all
  file-open "turtle_details.csv"
  let headings csv:from-row file-read-line
  set screen-headings sublist headings 0 4
  set battery-headings sublist headings 4 length headings

  while [ not file-at-end? ] [
    let data csv:from-row file-read-line
    create-turtles 1 [
      set turtle-screen-list sublist data 0 4
      set turtle-battery-list sublist data 4 length data
      set rating-each-year []

    ]
  ]

  file-close-all

  ask turtles [
    update-vals 12 5
    set rating-each-year lput turtle-sum-eval rating-each-year
  ]

end

Это более или менее то же самое, но есть некоторые важные изменения, такие как новый список под названием rating-each-year, который предназначен для того, чтобы черепахи могли отслеживать свой рейтинг на каждом тике.

Журналисты также в основном не изменились, за исключением того, что update-vals теперь является процедурой, специфичной для черепах, поэтому ее нужно вызывать с помощью ask turtles (или аналогичной). Кроме того, он принимает две переменные, одну с именем screen? и одну с именем battery?. Затем вы можете вызвать репортера, попросив черепаху: update-vals 12 24, и эта черепаха затем обновит свои значения для размера экрана 12 и времени автономной работы 24. Я включил всех трех репортеров для полноты картины, но два других не изменились. из моего ответа на ваш другой вопрос:

to update-vals [ screen? battery? ]
    set turtle-screen-eval turtle-screen-rating screen?
    set turtle-bat-eval turtle-battery-rating battery?
    set turtle-sum-eval turtle-screen-eval + turtle-bat-eval
end

to-report turtle-screen-rating [sc]
  let pos position sc screen-headings
  let turt-screen-rate-value item pos turtle-screen-list
  report turt-screen-rate-value
end

to-report turtle-battery-rating [bc]
  let pos position bc battery-headings
  let turt-bat-rate-value item pos turtle-battery-list
  report turt-bat-rate-value
end

Итак, теперь ваши черепашки могут в любое время обновить свой суммарный рейтинг в соответствии с комбинацией экрана и батареи, которую вы им назначили или которую они купили, как бы вы это ни настраивали. Вот пример go процедуры, в которой каждый тик заставляет их выбирать случайный возможный размер экрана и время автономной работы для оценки, а затем они добавляют это суммарное значение рейтинга в свой rating-each-year список. Когда проходит 20 тиков, процедура останавливается, и черепахи показывают свои списки в командном центре (длиной 21 элемент, так как они также включают значение из setup).

to go
  ifelse ticks < 20 [
    ask turtles [
      let screen-this-year one-of screen-headings
      let battery-this-year one-of battery-headings
      update-vals screen-this-year battery-this-year
      set rating-each-year lput turtle-sum-eval rating-each-year
    ]
  ]
  [
    ask turtles [
      show rating-each-year
    ]
    stop
  ]
  tick 
end

Конечно, в вашей модели вы, вероятно, не заставите их случайным образом выбирать значения — это было больше для того, чтобы показать, что они на самом деле делают. Я также должен упомянуть, что «turtle_details.csv» — это тот же файл, который я использовал для примера в последнем вопросе.

person Luke C    schedule 14.07.2017
comment
Большое спасибо. Позвольте мне задать несколько вопросов, чтобы, надеюсь, понять ваше решение. Почему вы добавили `set Turtle-Battery-List fput Item 0 Data Turtle-Battery-List`? - person user710; 14.07.2017
comment
Отличный вопрос - ответ... случайно. Это было пережитком того момента, когда мы обсуждали, что черепашки должны знать номер строки, из которой были извлечены значения их оценок. Я немного изменил процедуру установки — посмотрим, будет ли это иметь больше смысла. - person Luke C; 14.07.2017
comment
Спасибо. Я только что вспомнил, что вы упоминали об этом раньше, когда я спросил, что если я хочу сохранить столбец с номером строки и для второго подсписка. Однако сейчас мне это не нужно, поэтому текущая настройка больше помогает, чем предыдущая, в том, что я пытаюсь сделать. - person user710; 14.07.2017
comment
Да, это звучит правильно. Позвольте мне знать, если у вас есть какие-либо другие вопросы. - person Luke C; 14.07.2017
comment
Большое спасибо, Люк. В конце концов я смогу понять, как использовать ваше замечательное предложение, и оно выглядит великолепно. - person user710; 20.07.2017
comment
Эта ошибка говорит о том, что я не могу использовать go в контексте наблюдателя; go только turtle. Я заметил, что процедура в go имеет дело только с переменными потребителей, поэтому я не добавлял ask consumers внутрь процедуры. Я только что изменил go : to go ask consumers[ access-data-set] и вроде работает. - person user710; 20.07.2017
comment
Хорошо, рад помочь, и я рад, что вы разобрались! - person Luke C; 20.07.2017