Skip to content

Commit

Permalink
Dropped rate attribute and updated score, storage of cycles on main p…
Browse files Browse the repository at this point in the history
…age for each LO, added attractivity attribute, commented user interactions, removed total rates for data collector, removed graph section, currentCycle attribute. New functions to check sequential cycles to operations as go to main page and social media, attractivity updates according actions. Model iteraction through cycles.
  • Loading branch information
arbehr committed Apr 15, 2023
1 parent cd9dabc commit 1c3d3d8
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 114 deletions.
57 changes: 34 additions & 23 deletions examples/repository_usage/repository_usage/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,29 @@ def __init__(self, unique_id, on_main_page, model):
super().__init__(unique_id, model)
self.views = 0
self.downloads = 0
self.rates = 0
self.lastCycleDownloads = 0
#self.rates = 0
self.likes = 0
self.lastCycleLikes = 0
self.text = ""
self.score = 0
self.cyclesOnMainPage = []
self.isOnMainPage = on_main_page
self.showMainPage = model.showMainPage
self.attractivity = round(self.random.random(),2)
if (self.attractivity == 0.0):
self.attractivity = 0.01
#print(self.attractivity)

def step(self):
weights_sum = self.model.view_weight + self.model.download_weight + self.model.rate_weight + self.model.like_weight
weights_sum = self.model.view_weight + self.model.download_weight + self.model.like_weight #+ self.model.rate_weight
self.score = (self.model.view_weight * self.views) + (self.model.download_weight * self.downloads)
self.score = self.score + (self.model.rate_weight * self.rates) + (self.model.like_weight * self.likes)
self.score = self.score + (self.model.like_weight * self.likes) #+ (self.model.rate_weight * self.rates)
self.score = self.score / weights_sum
self.text = "ID: " + str(self.unique_id) + ". V:" + str(self.views)
self.text += " D:" + str(self.downloads) + " R:" + str(self.rates) + " L:" + str(self.likes)
self.text += " D:" + str(self.downloads) + " L:" + str(self.likes) #+ " R:" + str(self.rates)
self.text += " SCORE:" + str(float("{:.4f}".format(self.score)))
self.text += " ATT:" + str(self.attractivity)

class UserAgent(mesa.Agent):
"""An user agent that takes action in repository."""
Expand All @@ -46,48 +54,51 @@ def do_action(self):
cellmates = self.model.grid.get_cell_list_contents([self.pos])
self.canMove = False
if isinstance(cellmates[0], LearningObjectAgent):
print("Old action = " + str(self.action))
#print("Old action = " + str(self.action))

prob_action = self.random.randrange(0,100)
if self.action == 0 or self.action == 4:
print("Main page = " + self.model.mainPage)
prob_user_interest = round(self.random.random(),2)
if self.action == 0 :
#print("Main page = " + self.model.mainPage)
main_page_exp = 0
if((" " + str(cellmates[0].unique_id) + " ") in self.model.mainPage):
main_page_exp = 0.1
print("*** LO on main page ***")
if(prob_action <= (self.model.view_chance + main_page_exp) * 100):
print(str(self.unique_id) + " - Viewed LO! at " + str(cellmates[0].pos))
#print("*** LO on main page ***")
if(prob_user_interest + cellmates[0].attractivity + main_page_exp >= 1):
#print("User: " + str(self.unique_id) + " - Viewed LO(" + str(cellmates[0].unique_id) + ")! at " + str(cellmates[0].pos))
self.action = 1
cellmates[0].views += 1
else:
print(str(self.unique_id) + " - NOT Viewed LO! at " + str(cellmates[0].pos))
#print("User: " + str(self.unique_id) + " - NOT Viewed LO(" + str(cellmates[0].unique_id) + ")! at " + str(cellmates[0].pos))
self.canMove = True
elif self.action == 1:
if(prob_action <= self.model.download_chance * 100):
print(str(self.unique_id) + " - Downloaded LO! at " + str(cellmates[0].pos))
if(prob_user_interest + (cellmates[0].attractivity * self.model.download_chance) >= 1):
#print("User: " + str(self.unique_id) + " - Downloaded LO(" + str(cellmates[0].unique_id) + ")! at " + str(cellmates[0].pos))
self.action = 2
cellmates[0].downloads += 1
else:
print(str(self.unique_id) + " - NOT Downloaded LO! at " + str(cellmates[0].pos))
#print("User: " + str(self.unique_id) + " - NOT Downloaded LO(" + str(cellmates[0].unique_id) + ")! at " + str(cellmates[0].pos))
self.action = 0
self.canMove = True
elif self.action == 2:
if(prob_action <= self.model.like_chance * 100):
print(str(self.unique_id) + " - Liked LO! at " + str(cellmates[0].pos))
if(prob_user_interest + (cellmates[0].attractivity * self.model.like_chance) >= 1):
#print("User: " + str(self.unique_id) + " - Liked LO(" + str(cellmates[0].unique_id) + ")! at " + str(cellmates[0].pos))
cellmates[0].likes += 1
self.action = 3
else:
print(str(self.unique_id) + " - NOT Liked LO! at " + str(cellmates[0].pos) + " Let's try to rate")
self.action = -3
elif self.action == 3 or self.action == -3:
if(prob_action <= self.model.rate_chance * 100):
#self.action = 3
#else:
#print("User: " + str(self.unique_id) + " - NOT Liked LO(" + str(cellmates[0].unique_id) + ")! at " + str(cellmates[0].pos)) #+ " Let's try to rate")
#self.action = -3
self.canMove = True
self.action = 0
'''elif self.action == 3 or self.action == -3:
if(prob_user_interest <= self.model.rate_chance * 100):
print(str(self.unique_id) + " - Rated LO! at " + str(cellmates[0].pos))
cellmates[0].rates += 1
self.action = 4
else:
print(str(self.unique_id) + " - NOT Rated LO! at " + str(cellmates[0].pos))
self.action = 0
self.canMove = True
'''

def move(self):
x = self.random.randrange(self.model.grid.width)
Expand Down
138 changes: 104 additions & 34 deletions examples/repository_usage/repository_usage/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,9 @@ def get_total_views(model):
"""sum of all agents' views"""
agent_views = [a.views for a in model.schedule.agents if isinstance(a, LearningObjectAgent)]
# return the sum of agents' views
print(np.sum(agent_views))
#print(np.sum(agent_views))
return str(np.sum(agent_views))

def get_total_rates(model):
"""sum of all agents' rates"""
agent_rates = [a.rates for a in model.schedule.agents if isinstance(a, LearningObjectAgent)]
# return the sum of agents' rates
return str(np.sum(agent_rates))

def get_total_likes(model):
"""sum of all agents' likes"""
agent_likes = [a.likes for a in model.schedule.agents if isinstance(a, LearningObjectAgent)]
Expand All @@ -37,14 +31,14 @@ class RepositoryUsageModel(mesa.Model):
The agent color represent the action performed: download, view, rate, or like."""

def __init__(self, init_users=10, view_weight=2, download_weight=4, rate_weight=8, like_weight=7,
view_chance=0.6, download_chance=0.4, rate_chance=0.15, like_chance=0.2,
view_chance=0.6, download_chance=0.5, rate_chance=0.15, like_chance=0.3,
max_steps=30, h_size=10, v_size=10, width=10, height=10, mainPageWidth=5, showMainPage=True):
self.running = True
self.num_agents = init_users
self.grid = mesa.space.MultiGrid(width, height, True)
self.schedule = mesa.time.RandomActivation(self)
self.max_steps = max_steps
self.mainPage = " "
self.mainPage = []
self.view_chance = view_chance
self.download_chance = download_chance
self.like_chance = like_chance
Expand All @@ -54,32 +48,28 @@ def __init__(self, init_users=10, view_weight=2, download_weight=4, rate_weight=
self.rate_weight = rate_weight
self.like_weight = like_weight
self.showMainPage = showMainPage
self.G = nx.Graph()

self.currentCycle = 0

# Create learning object agents, one in each cell, static
id = 0
for i in range(self.grid.width):
for j in range(self.grid.height):
a = LearningObjectAgent(id, False, self)
#to the networkgrid (grid2)
self.G.add_node(id)
id += 1
self.grid.place_agent(a, (i, j))
self.schedule.add(a)
# Get five random agents to put on main page and update attribute
# Get five random agents to put on main page in first time and update attribute
pickedIds = 0
while pickedIds < mainPageWidth:
random_id = self.random.randrange(id)
if((" " + str(random_id) + " ") not in self.mainPage):
if(random_id not in self.mainPage):
pickedIds += 1
self.mainPage += str(random_id) + " "
self.mainPage.append(random_id)
a = self.schedule.agents.__getitem__(random_id)
a.isOnMainPage = True
a.cyclesOnMainPage.append(self.currentCycle)

# Add edges for nodes
self.G.add_edges_from([(1,5),(1,3),(5,6),(20,50),(11,12)])
self.G.add_edge(1, 2)

# Create user agents
for i in range(self.num_agents):
a = UserAgent(id, self)
Expand All @@ -96,7 +86,7 @@ def __init__(self, init_users=10, view_weight=2, download_weight=4, rate_weight=
model_reporters={
"Views": get_total_views,
"Downloads": get_total_downloads,
"Rates": get_total_rates,
#"Rates": get_total_rates,
"Likes": get_total_likes,
},
)
Expand All @@ -109,41 +99,121 @@ def step(self):
self.schedule.step()
if(self.schedule.steps == self.max_steps):
self.running = False



def run_model(self):
for i in range(self.run_time):
self.step()

"""A model with parameters setted in cosntructor and run it for 100 steps"""

model = RepositoryUsageModel(init_users=30, width=10, height=10)
for i in range(100):
model.step()

def isSequential(self, size, list):
#print(list)
for i in range(0,size-1):
#print(list[-size+i] + 1)
#print(list[-size+i+1])
if(list[-size+i] + 1 != list[-size+i+1]):
return False
return True

def checkSucessiveTimesOnMainPage(self, max, gain, type):
for cell in self.grid.coord_iter():
cell_content, x, y = cell
a = self.schedule.agents.__getitem__(cell_content[0].unique_id)
if((len(a.cyclesOnMainPage) >= max) and
(self.isSequential(max, a.cyclesOnMainPage)) and
(a.cyclesOnMainPage[-1] == self.currentCycle)):
if(len(a.cyclesOnMainPage) > max and
(a.cyclesOnMainPage[-max-1] +1 == a.cyclesOnMainPage[-max])):
print("LO = " + str(a.unique_id) + " já foi para " + type + ".")
print(a.cyclesOnMainPage)
else:
print("Muitas vezes seguidas escaparate! Vai para " + type + ", LO = " + str(a.unique_id))
a.attractivity += gain
print(a.cyclesOnMainPage)

def updateAttractivity(self):
for cell in self.grid.coord_iter():
cell_content, x, y = cell
a = self.schedule.agents.__getitem__(cell_content[0].unique_id)
if(a.downloads - a.lastCycleDownloads >= 10):
a.attractivity += 0.2
print("Attractivity updated by download. LO = " + str(a.unique_id) + " with delta = " + str(a.downloads - a.lastCycleDownloads))
if(a.likes - a.lastCycleLikes >= 5):
a.attractivity += 0.2
print("Attractivity updated by like. LO = " + str(a.unique_id) + " with delta = " + str(a.likes - a.lastCycleLikes))

def updateMainPageLikeDownloads(self):
d = {}
for cell in self.grid.coord_iter():
cell_content, x, y = cell
a = self.schedule.agents.__getitem__(cell_content[0].unique_id)
d[cell_content[0].unique_id] = a.score
a.lastCycleLikes = a.likes
a.lastCycleDownloads = a.downloads
#print(d)
sorted_dict = dict(sorted(d.items(), key=lambda x:x[1]))
#print(sorted_dict)
print("Scores:")
print("First One: " + str(list(sorted_dict.values())[0]) + " LO = " + str(list(sorted_dict.keys())[0]))
print("Last One: " + str(list(sorted_dict.values())[-1]) + " LO = " + str(list(sorted_dict.keys())[-1]))
five_first = 0
self.mainPage = []
for key in sorted_dict.keys():
self.mainPage.append(key)
a = self.schedule.agents.__getitem__(key)
a.cyclesOnMainPage.append(model.currentCycle)
five_first += 1
#print(sorted_dict)
if(five_first == 5):
break

"""A model with parameters setted in cosntructor and run in cycles for 100 steps"""
cycles = 100
model = RepositoryUsageModel(init_users=10, width=10, height=10)

for j in range(cycles):
print(">>>>> Starting cycle #" + str(j))
if (j > 0):
model.updateMainPageLikeDownloads()
print("New main page:")
else:
print("Old main page:")

print(sorted(model.mainPage))

for i in range(100):
model.step()


model.updateAttractivity()
model.checkSucessiveTimesOnMainPage(4, 0.1, "redes sociais")
model.checkSucessiveTimesOnMainPage(8, 0.3, "refatoração")
model.currentCycle += 1


scores = np.zeros((model.grid.width, model.grid.height))
views = np.zeros((model.grid.width, model.grid.height))
downloads = np.zeros((model.grid.width, model.grid.height))
likes = np.zeros((model.grid.width, model.grid.height))
rates = np.zeros((model.grid.width, model.grid.height))
#rates = np.zeros((model.grid.width, model.grid.height))

for cell in model.grid.coord_iter():
cell_content, x, y = cell
a = model.schedule.agents.__getitem__(x+y)
a = model.schedule.agents.__getitem__(cell_content[0].unique_id)
scores[x][y] = a.score
views[x][y] = a.views
downloads[x][y] = a.downloads
likes[x][y] = a.likes
rates[x][y] = a.rates
#rates[x][y] = a.rates

#print(scores)

con = np.concatenate((rates,likes,downloads,views))
name = ['Rates', 'Likes', 'Downloads', 'Views']
con = np.concatenate((likes,downloads,views))
name = ['Likes', 'Downloads', 'Views']
#magnitude = np.linalg.norm(con)
#normalized_con = con / magnitude

newarr = np.array_split(con, 4)
newarr = np.array_split(con, 3)
min_attr = np.min([np.min(con)])
max_attr = np.max([np.max(con)])

Expand All @@ -153,7 +223,7 @@ def run_model(self):
fig = plt.figure(constrained_layout=True)
(subfig_l, subfig_r) = fig.subfigures(nrows=1, ncols=2)

axes_l = subfig_l.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
axes_l = subfig_l.subplots(nrows=1, ncols=3, sharex=True, sharey=True)
for i,ax in enumerate(axes_l.flat):
im = ax.imshow(newarr[i], interpolation='nearest', vmin=min_attr, vmax=max_attr)
ax.set_title(name[i])
Expand All @@ -166,4 +236,4 @@ def run_model(self):
axes_r.set_title("Scores")
subfig_r.colorbar(im, ax=axes_r)

plt.show()
plt.show()
Loading

0 comments on commit 1c3d3d8

Please sign in to comment.