Netlogo: create subset of turtles to use later - social-networking

I'm constructing a model to research opinion dynamics given certain network structures. In the model, there is a hypothetical 'dictator' who can hand out resources (or 'bribes') to certain nodes in the network. Currently, the dictator has three strategies: 1) handing out bribes to the nodes in the network with the most positive opinion. 2) handing out bribes to the nodes in the network with the most links. And 3) handing out bribes to a random set of N nodes.
I got strategy 1 and 2 working correctly, but can't get 3 to work. Currently, the procedure looks like this
to go
handout-bribes
include-lpr
update-motivation
update-participation
ask nodes [update-look-of-nodes]
tick
end
;;; Bribes are handed out either to the top N nodes with the most positive motivation, the top N nodes with the most ties, or randomly
to handout-bribes
if strategy-of-dictator = "targeted-opinion" [
ask max-n-of (num-nodes * percentage-receiving-bribes) nodes [( - total-motivation) ] [set bribes (bribes + height-of-bribes)]]
if strategy-of-dictator = "targeted-ties" [
ask max-n-of (num-nodes * percentage-receiving-bribes) nodes [count my-links] [set bribes (bribes + height-of-bribes)]]
if strategy-of-dictator = "random" [
ask n-of (num-nodes * percentage-receiving-bribes) nodes [set bribes (bribes + height-of-bribes)]]
end
With this code a new random group of nodes to receive bribes is chosen each tick. What I want however, is that a the start of the procedure a group of N nodes is chosen who will receive bribes after each tick. How should I code this? I was thinking about creating a subset of nodes at setup, and calling these in the procedure. But I got no clue how to do this.
Thanks!

Related

Finding algorithm that minimizes a cost function

I have a restroom that I need to place at some point. I want the restroom's placement to minimize the total distance people have to travel to get there.
So I have x apartments, and each house has n people living in each apartment, so the apartments would be like a_1, a_2, a_3, ... a_x and the number of people in a_1 would be n_1, a_2 would be n_2, etc. No two apartments can be in the same space and each apartment has a positive number of people.
So I know the distance between an apartment a_1 and the proposed bathroom, placed at a, would be |a_1 - a|.
MY WORKING:
I defined a cost function, C(a) = SUM[from i = 1 to x] (n_i)|a_i - a|. I want to find the location a that minimizes this cost function, given two arrays - one for the location of the apartments and one for the number of people in each apartment. I want my algorithm to be in O(n) time.
I was thinking of representing this as a graph and using MSTs or Djikstra's but that would not meet the O(n) runtime. Clearly, there must be something I can do without graphs, but I am unsure.
My understanding of your problem:
You have a once dimensional line with points a1,...,an. Each point has a value n1,....n, and you need to pick a point a that minimizes the cost function
SUM[from i = 1 to x] (n_i)|a_i - a|.
Lets assume our input a1...an is sorted.
Our strategy will be a sweep from left to right, calculating possible a on the way.
Things we will keep track of:
total_n : the total number of people
left_n : the number of people living to the left or at our current position
right_n : the number of people living to the right of our current position
a: our current postition
Calculate:
C(a)
left_n = n1
right_n = total_n - left_n
Now we consider what happens to the sum if we move our restroom to the right 1 step. The people on the left get 1 step further away, but the people on the right get 1 step closer.
We can say that C(a+1) = C(a) +left_n -right_n
If the range an-a1 is fairly small, we can use this and just step through the range using this formula to update the sum. Note that when this sum starts increasing we have gone too far and can safely stop.
However, if the apartments are very far apart we cannot step 1 by 1 unit. We need instead to step apartment by apartment. Note
C(a[i]) = C(a[i-1]) + left_n*(a[i]-a[a-1]) - right_n*(a[i]-a[i-1])
If at any point C(a[i]) > C(a[i-1]) we know that the correct position of the restroom is somewhere between i and i-1.
We can calculate that position, lets call it x.
The sum at x is C(a[i-1]) + left_n*(x-a[i-1]) - right_n*(x-a[i-1]) and we want to minimize this. Note that everything but x is known values.
We can simplify to
f(x) = C(a[i-1]) + left_n*x-left_n*a[i-1]) - right_n*x-left_n*a[i-1])
Constant terms cannot affect our decision so we are actually looking to minize
f(x) = x*(left_n-right_n)
We see that if left_n < right_n we want the restroom to be at i+1, but if left_n > right_n we want the restroom to be at i.
We need to at most do this calculation at each apartment, so the running time is O(n).

Find the path in a graph, that requires the least amount of nodes to visit

I'm looking for an algorithm to find the shortest way in a non-circular graph. However, the shortest path is not defined as the one with the least weight, but the one with the least number of nodes to visit before reaching the destination.
Let me give you an example: Let's assume you use bad timer app on your phone, which timer is limited to half an hour. There are three buttons:
add 10 minutes
add 1 minute
subtract one minute
The initial value is zero. The input range is 0 to 30 minutes. We now want to set a timer for let's say 29 min. The shortest path to accomplish this is by hitting add 10 min three times and subtract 1 min one time.
We represent every permutation of button presses in a graph (where every node represents a click on one of the three buttons). We are now looking for a way from start to a specific number, that has the least amount of button presses on it.
The problem can be solved using breadth first search (BFS). Problem is given a starting time (which we consider as starting node of the graph) and a target time (which we consider as destination node). In every step, we can do either of the following with the current time:
Add 10 minutes
Add 1 minute
Subtract 1 minute
Now, the nodes of the graph will be the time we can reach using either of the above steps. For example, starting from time 0 (consider it as node-id 0) we can reach to wither 10, 1, or -1 (i.e., nodes) in one step. So, in one step we discover three different nodes of the graph and non of them is our destination node.
With this three newly discovered nodes, we can do the similar moves and reach to some new nodes which are 2-step away from the source node (i.e., time 0). Here is the list of nodes we can discover in our second step:
From 10 to: 20, 11, 9
From 1 to: 11, 2, 0
From -1 to: 9, 0, -2
There are couple of thing we can notice from here:
If we discover a node which we never discovered before, then the steps it required to discover is the shortest distance. For example, we can reach to node 9 by 2 steps from the source node 0 (here we can see, 9 can be reached from both nodes 10 and -1), and clearly it is the shortest distance for node 9.
The graph can be circular. For example, there is an edge from node 0 to node -1, and from node -1 to node 0. You need to handle that.
So, it is clear now that we transform this problem to a standard BFS problem. Now, we can solve it by the following pseudo code:
Shortest-Path(initial-time, target-time):
Queue<time> Q
Map<time, step> M // this map will help tracking whether we discover a node before or not
Q.insert(initial-time)
M[initial-time] = 0
while(!Q.empty):
current-time = Q.front()
Q.pop()
if current-time is equal to target-time:
return M[current-time]
if (current-time + 10) is not in the M:
Q.push(current-time + 10)
M[(current-time + 10)] = M[current-time] + 1
if (current-time + 1) is not in the M:
Q.push(current-time + 1)
M[(current-time + 1)] = M[current-time] + 1
if (current-time - 1) is not in the M:
Q.push(current-time - 1)
M[(current-time - 1)] = M[current-time] + 1
Instead of thinking of the problem as a graph traversal problem, you can solve it simply by performing BFS on a tree that starts with a single root node and grows over time:
#!/usr/bin/python3
DESIRED_SUM = 29
SET = [-1, 1, 10]
QUEUE = [(0, [])] # For BFS
ANSWER = {} # For Dynamic Programming
while True:
(cur_sum, elements) = QUEUE.pop(0)
if cur_sum not in ANSWER:
ANSWER[cur_sum] = elements
if cur_sum == DESIRED_SUM:
break
for num in SET:
new_sum = cur_sum + num
if new_sum not in ANSWER:
new_elements = elements.copy()
new_elements.append(num)
QUEUE.append((new_sum, new_elements))
for key, item in ANSWER.items():
print("{0}: {1}".format(key, item))
Every time you are appending to the QUEUE, you are effectively adding leaf nodes. If you just perform BFS without storing the results (i.e. dynamic programming), then you will hit exponential time. The way the above code copies and carries around the list of elements is highly inefficient. You could instead store ANSWER[28] = ANSWER[29] - 1, for example, such that when you actually want to retrieve the full list of elements for a given sum, you can recursively follow the ANSWER to retrieve it.
Note that the above program will never terminate if the DESIRED_SUM can't be derived from the given list of elements.

Shortest Path for n entities

I'm trying to solve a problem that is about minimizing the distance traveled by a group of n entities who have to go trough a group of x points in a given order.
The n entities all start in the same position (1,1) and then I'm given x points that are in a queue and have to be "answered" in the correct order. However, I want the distance to be minimal.
My approach to the algorithm so far was to order the entities in increasing order of their distance to the x that is next in line. Then, I'd check, from the ones that are closer to the ones that are the furthest away, if this distance to the next in line is bigger than the distance to the one that comes afterwards to minimize the distance. The closest one to not fulfill this condition went to answer. If all were closer to the x that came afterwards, I'd reorder them in increasing order of distance to the one that came afterwards and send the furthest away from this to answer the x. Since this is a test problem I'm doing as practice for a competition I know what the result should be for my test case and it seems I'm doing this wrong.
How should I implement such an algorithm that guarantees that the distance is minimal?
The algorithm you've described sounds like a greedy search algorithm. Greedy algorithms are not guaranteed to find optimal solutions except under specific conditions that don't seem to hold here.
This looks like a candidate for a dynamic programming formulation. Alternatively, you can use heuristic search such as the A* search algorithm. I'd go with the latter if I was in the competition. See the link for a description of how the algorithm works, how to implement it, and how you might apply it to your problem.
Although since the points need to be visited in order, there is a bound on the number of possible arrangements, I couldn't think of a more efficient way than the following formulation. Let f(ns, i) represent the optimal arrangement up to the ith point, where ns is the list of the last chosen point for each entity that has at least one point. Then we have at most two choices: either start a new entity if we haven't run out, or try the current point as the next visit for each entity.
Python recursion:
import math
def d(p1, p2):
return math.sqrt(math.pow(p1[0] - p2[0], 2) + math.pow(p1[1] - p2[1], 2))
def f(ps, n):
def g(ns, i):
if i == len(ps):
return 0
# start a new entity if we haven't run out
best = d((0,0), ps[i]) + g(ns[:] + [i], i + 1) if len(ns) < n else float('inf')
# try the current point as the next visit for each entity
for entity_idx, point_idx in enumerate(ns):
_ns = ns[:]
_ns[entity_idx] = i
best = min(best, d(ps[point_idx], ps[i]) + g(_ns, i + 1))
return best
return d((0,0), ps[0]) + g([0], 1)
Output:
"""
p5
p3
p1
(0,0) p4 p6
p2
"""
points = [(0,1), (0,-1), (0,2), (2,0), (0,3), (3,0)]
print f(points, 3) # 7.0

Finding if data communication is possible

N routers are provided on x-axis and want to communicate to each other. One router can send a message to another one if the distance between them is less or equal to K.
Given P pairs of routers, which want to send messages.We need to tell with "Y" or "N" weather data transmission between that pair is possible or not.
Note : More than 1 router can be on the same point on the X-axis.
Constraints :
1 ≤ N, P ≤ 10^5
0 ≤ Ai, K ≤ 10^9
1 ≤ A, B ≤ N
So i want a pretty efficient algorithm for each query.
Let if we have 5 routers,K=3 and 2 queries as follow :
Position of routers : = 0 3 8 5 12
Query 1 : 1 2
Here answer is "Y" as both are in range of each other
Query 2 : 1 3
Here answer is "Y" as both are in range of each other
For pair (1, 3) router 1 can send a message to router 2, router 2 can send it to router 4 and it can send it to router 3.
First map the router position/distance:
List<int> Routers=new List<int>();
Routers.Add(0);
//....
Routers.Add(12);
Create the pairings:
class Pairs
{
int[2] Pair;
}
List<Pair> Pairings=new List<Pair>();
Pairings.Add({Routers.IndexOf(0),Routers.IndexOf(1)});
Pairings.Add({Routers.IndexOf(0),Routers.IndexOf(2)});
Create the check method:
private bool CanCommunicate(intx i1,inti2)
{
if (Math.Abs(i1-i2)<=K
return true;
else
return false;
}
Implement the alg:
foreach (Pair p in Pairings)
{
if(CanCommunicate(p[0],p[1])
return "Y";;
else
return "N";
}
Code is in C#
The routers are on the x axis, so two routers can talk directly if the difference between them is less than the bounds, and two can talk indirectly if there is no gap between routers on the path between them on the x axis so large that messages cannot get through.
So sort the routers in order of ascending position on the x axis and then consider them in order of ascending x and break them into runs of routers which contain no gaps that are too big. Number the runs and then two routers can communicate if and only if they are both in the same number run.
Given indirect communication, I would begin by finding the gaps, the places along the x-axis where there is too big a separation between two adjacent routers for them to communicate.
For each router, record the location of the next gap to the right. Treat the end of the line as a gap.
Two routers can communicate if, and only if, they share the same next gap.
============================================================================
Sort the list of routers in ascending x co-ordinate order
Initialize integer groupIndex to 0.
For each router in x co-ordinate order:
Mark it with the current groupIndex
If there is a next router and it is more than distance K away, increment groupIndex
Two routers can communicate if, and only if, they are marked with the same groupIndex.

How to store a Euler graph struct?

I'm working around the Euler Path issue and found a problem:How to define or store a Euler graph struct?
An usual way is using an "Adjoint Matrix",C[i][j] is defined to store the edge between i-j.It's concise and effective! But this kind of matrix is limited by the situation that the edge between 2 nodes is unique (figure 1).
class EulerPath
{
int[][] c;//adjoint matrix,c[i][j] means the edge between i and j
}
What if there are several edges (figure 2)?My solution might be using customized class ,like "Graph","Node","Edge" to store a graph,but dividing the graph into some discrete structs ,which means we have to take more class details into consideration,may hurt the efficiency and concision. So I'm very eager to hear your advice!Thanks a lot!
class EulerPath
{
class Graph
{
Node[] Nodes;
Edge[] Edges;
}
class Node{...}
class Edge{...}
}
You can use an adjacency matrix to store graphs with multi-edges. You just let the value of c[i][j] be the number of times that vertex i is adjacent to vertex j. In your first case, it's 1, in your second case, it's 3. See also Wikipedia -- adjacency matrices aren't defined as being composed of only 1 and 0, that's just the special case of an adjacency matrix for a simple graph.
EDIT: You can represent your second graph in an adjacency matrix like this:
1 2 3 4
1 0 3 1 1
2 3 0 1 1
3 1 1 0 0
4 1 1 0 0
You can do this in at least three ways:
Adjacency list
Meaning that you have a 2D array called al[N][N]
al[N][N] This N is the node index
al[N][N] This N is the neighbor node index
Example, a graph with this input:
0 => 1
1 => 2
2 => 3
3 => 1
The adjacency list will look like this:
0 [1]
1 [2,3]
2 [1,3]
3 [1,2]
PS: Since this is a 2D array, and not all horizontal cells are going to be used, you need to keep track of the number of connected neighbours for each graph index because some programming languages initialise array values with a zero which is a node index in the graph. This can be done easily by creating another array that will count the number of neighbours for each graph index. Example of this case: numLinks: [1,2,2,2]
Matrix
With a matrix, you create an N x N 2D array, and you put a 1 value in the intersection of row col neighobor nodes:
Example with the same input above:
0 1 2 3
0 0 1 0 0
1 1 0 1 1
2 0 1 0 1
3 0 1 1 0
Class Node
The last method is creating a class called Node that contain a dynamic array of type Node. And you can store in this array the other nodes connected
Consider using a vector of linked list. Add a class that will have a field for a Vertex as well as the Weight (let's name it Entry). Your weights should be preferably another vector or linked list (preferably ll) which will contain all possible weights to the according Vertex. Your main class will have a vector of vectors, or a vector of linked lists (I'd prefer linked lists since you will most likely not need random access, being forced to iterate through every Entry when performing any operation). You main class will have one more vector containing all vertices. In C++ this would look like this:
class Graph{
std::vector<std::forward_list<Entry>> adj_list;
std::vector<Vertex> vertices;
};
Where the Vertex that corresponds to vertices[i] has the corresponding list in adj_list[i]. Since every Entry contains the info regarding the Vertex to which you are connected and the according weights, you will have your graph represented by this class.
Efficiency for what type of operation?
If you want to find a route between two IP addresses on the internet, then your adjacency matrix might be a million nodes squared, ie a gigabyte of entries. And as finding all the nodes connected to a given node goes up as n, you could be looking at a million lookups per node just to find the nodes connected to that node. Horribly inefficient.
If your problem only involves a few nodes and is run infrequently, then adjacency matrices are simple and intuitive.
For most problems which involve traversing graphs, a better solution could be to create a class called node, which has a property a collection (say a List) of all the nodes it is connected to. For most real world applications, the list of connected nodes is much less than the total number of all nodes, so this works out as more compact. Plus it is highly efficient in finding edges - you can get a list of all connected nodes in fixed time per node.
If you use this structure, where you have a node class which contains as a property a collection of all the nodes it is connected to, then when you create a new edge (say between node A and node B) then you add B to the collection of nodes to which A is connected, and A to the collection of nodes to which B is connected. Excuse my Java/C#, something like
class Node{
Arraylist<Node> connectedNodes;
public Node() // initializer
{
connectedNodes = new ArrayList<Node>;
}
}
// and somewhere else you have this definition:
public addEdgeBetween(Node firstNode, Node secondNode) {
firstNode.connectedNodes.Add(secondNode);
secondNode.connectedNodes.Add(firstNode);
}
And similarly to delete an edge, remove the reference in A to B's collection and vice versa. There is no need to define a separate edge class, edges are implicit in the structure which cross-links the two nodes.
And that's about all you have to do to implement this structure, which is (for most real world problems) uses far less memory than an adjacency matrix, is much faster for large numbers of nodes for most problems, and is ultimately far more flexible.
Defining a node class also opens up a logical place to add enhancements of many sorts. For example, you might decide to generate for each node a list of all the nodes which are two steps away, because this improves path finding. You can easily add this in as another collection within the node class; this would be a pretty messy thing to do with adjacency matrices. You can obviously squeeze a lot more functionality into a class than a into a matrix of ints.
Your question concerning multiple links is unclear to me. If you want multiple edges between the same two points, then this can be accommodated in both ways of doing it. In adjacency matrices, simply have a number at that row and column which indicates the number of links. If you use a node class, just add each edge separately. Similarly directional graphs; an edge pointing from A to B has a reference to B in A's list of connected nodes, but B doesn't have A in its list.

Resources