001 /**
002 * "TRMSim-WSN, Trust and Reputation Models Simulator for Wireless
003 * Sensor Networks" is free software: you can redistribute it and/or
004 * modify it under the terms of the GNU Lesser General Public License
005 * as published by the Free Software Foundation, either version 3 of
006 * the License, or (at your option) any later version always keeping
007 * the additional terms specified in this license.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 * GNU Lesser General Public License for more details.
013 *
014 *
015 * Additional Terms of this License
016 * --------------------------------
017 *
018 * 1. It is Required the preservation of specified reasonable legal notices
019 * and author attributions in that material and in the Appropriate Legal
020 * Notices displayed by works containing it.
021 *
022 * 2. It is limited the use for publicity purposes of names of licensors or
023 * authors of the material.
024 *
025 * 3. It is Required indemnification of licensors and authors of that material
026 * by anyone who conveys the material (or modified versions of it) with
027 * contractual assumptions of liability to the recipient, for any liability
028 * that these contractual assumptions directly impose on those licensors
029 * and authors.
030 *
031 * 4. It is Prohibited misrepresentation of the origin of that material, and it is
032 * required that modified versions of such material be marked in reasonable
033 * ways as different from the original version.
034 *
035 * 5. It is Declined to grant rights under trademark law for use of some trade
036 * names, trademarks, or service marks.
037 *
038 * You should have received a copy of the GNU Lesser General Public License
039 * along with this program (lgpl.txt). If not, see <http://www.gnu.org/licenses/>
040 */
041
042 package es.ants.felixgm.trmsim_wsn.network;
043
044 import es.ants.felixgm.trmsim_wsn.search.ISearchCondition;
045 import es.ants.felixgm.trmsim_wsn.search.IsClientSearchCondition;
046 import es.ants.felixgm.trmsim_wsn.search.IsServerSearchCondition;
047 import java.io.BufferedWriter;
048 import java.io.File;
049 import java.io.FileWriter;
050
051 import java.util.Iterator;
052 import java.util.Collection;
053 import java.util.ArrayList;
054
055 import java.util.Vector;
056 import javax.xml.parsers.DocumentBuilder;
057 import javax.xml.parsers.DocumentBuilderFactory;
058
059 import org.w3c.dom.Document;
060 import org.w3c.dom.NamedNodeMap;
061 import org.w3c.dom.NodeList;
062
063 /**
064 * <p>This class models a P2P, Ad-hoc or Wireless Sensor Network, or even a
065 * multi-agent system.</p>
066 * <p>It is composed of several clients requesting services and servers offering services</p>
067 * <p><a name="xmlFileStructure"></a>The constructor
068 * {@link #Network Network}
069 * requires a XML file following the next structure:</p>
070 * <pre>
071 * <?xml version="1.0" encoding="UTF-8"?>
072 * <wsn>
073 * <client id="1" x="30.5" y="56.2">
074 * <server id="2"/>
075 * <server id="3"/>
076 * </client>
077 * <client id="7" x="10.3" y="26.4">
078 * <server id="4"/>
079 * <server id="6"/>
080 * </client>
081 * <server id="2" x="14.8" y="63.7">
082 * <service id="Relay" goodness="1.0"/>
083 * <server id="4"/>
084 * <server id="5"/>
085 * <client id="1"/>
086 * </server>
087 * <server id="3" x="29.7" y="73.7">
088 * <service id="Relay" goodness="1.0"/>
089 * <service id="Service 1" goodness="0.05"/>
090 * <server id="4"/>
091 * </server>
092 * <server id="4" x="38.4" y="56.2">
093 * <service id="Relay" goodness="1.0"/>
094 * <server id="6"/>
095 * </server>
096 * <server id="5" x="95.6" y="36.8">
097 * <service id="Relay" goodness="1.0"/>
098 * <service id="Service 1" goodness="0.12"/>
099 * <server id="6"/>
100 * <client id="7"/>
101 * </server>
102 * <server id="6" x="53.5" y="97.4">
103 * <service id="Relay" goodness="1.0"/>
104 * <service id="Service 1" goodness="0.98"/>
105 * <server id="3"/>
106 * </server>
107 * </tacs>
108 * </pre>
109 * <p><a href="http://ants.dif.um.es/~felixgm/research/trmsim-wsn/resources/wsn1.xml" target=_blank">
110 * This file</a> represents the following network:</p>
111 * <img src="http://ants.dif.um.es/~felixgm/research/trmsim-wsn/img/wsn1.gif">
112 <font color="#FF0000">
113 <p><strong>A subclass of this class, modeling the specific network, has to be
114 implemented in order to add a new Trust and Reputation Model</strong></p>
115 </font>
116 * @author <a href="http://ants.dif.um.es/~felixgm/en" target="_blank">Félix Gómez Mármol</a>, <a href="http://webs.um.es/gregorio" target="_blank">Gregorio Martínez Pérez</a>
117 * @version 0.5
118 * @since 0.1
119 */
120 public abstract class Network {
121 /** Maximum distance between two nodes in the network */
122 protected static final double maxDistance = 100.0;
123 /** The clients requesting services */
124 protected Collection<Sensor> clients;
125 /** The servers offering services */
126 protected Collection<Sensor> servers;
127 /** All the sensors composing the network */
128 protected Collection<Sensor> sensors;
129 /** All the services offered by the network */
130 protected Collection<Service> services;
131
132 /**
133 * This constructor creates a new Network from a given set of clients,
134 * servers and services
135 * @param clients The clients requesting services
136 * @param servers The servers offering services
137 * @param services All the services offered by the network
138 */
139 public Network(Collection<Sensor> clients, Collection<Sensor> servers, Collection<Service> services) {
140 this.clients = clients;
141 this.servers = servers;
142
143 sensors = new ArrayList<Sensor>();
144 if (clients != null)
145 for (Sensor client : clients)
146 sensors.add(client);
147 if (servers != null)
148 for (Sensor server : servers)
149 sensors.add(server);
150
151 this.services = services;
152 }
153
154 /**
155 * This constructor creates a new random Network using the given parameters
156 * @param numSensors Number of sensors composing the network
157 * @param probClients Probability of a sensor to act as a client requesting services
158 * @param rangeFactor Maximum wireless range of every sensor. It determines the neighborhood of every sensor
159 * @param probServices A collection of probabilities of offering a certain service, one per service
160 * @param probGoodness A collection of goodnesses about offering a certain service, one per service
161 * @param services All the services offered by the generated Network
162 */
163 public Network(
164 int numSensors,
165 double probClients,
166 double rangeFactor,
167 Collection<Double> probServices,
168 Collection<Double> probGoodness,
169 Collection<Service> services) {
170 clients = new ArrayList<Sensor>();
171 servers = new ArrayList<Sensor>();
172 sensors = new ArrayList<Sensor>();
173 this.services = new ArrayList<Service>();
174
175 Sensor.resetId();
176 Sensor.setMaxDistance(maxDistance);
177
178 for (int i = 0; i < numSensors; i++) {
179 if (Math.random() <= probClients) {
180 Sensor client = newSensor();
181 clients.add(client);
182 sensors.add(client);
183 } else {
184 Sensor server = newSensor();
185 servers.add(server);
186 sensors.add(server);
187
188 Iterator<Double> itProbServices = probServices.iterator();
189 Iterator<Double> itProbGoodness = probGoodness.iterator();
190 for (Service service : services)
191 if (Math.random() <= itProbServices.next().doubleValue()) {
192 if (Math.random() <= itProbGoodness.next().doubleValue())
193 server.addService(service, 1.0);
194 else
195 server.addService(service, 0.0);
196
197 if (!this.services.contains(service))
198 this.services.add(service);
199 }
200 }
201 }
202
203 if (clients.size() == 0) {
204 Sensor client = newSensor();
205 clients.add(client);
206 sensors.add(client);
207 }
208
209 // We are going to link the sensors in the network.
210 double rangeThreshold = rangeFactor*Math.sqrt(2.0)*maxDistance;
211 for (Sensor server : servers) {
212 for (Sensor client : clients)
213 if (server.distance(client) < rangeThreshold) {
214 client.addLink(server);
215 server.addLink(client);
216 }
217
218 for (Sensor server2 : servers)
219 if ((!server.equals(server2)) && (server.distance(server2) < rangeThreshold)) {
220 server.addLink(server2);
221 server2.addLink(server);
222 }
223 }
224
225 for (Sensor client1 : clients) {
226 for (Sensor client2 : clients)
227 if ((!client1.equals(client2)) && (client1.distance(client2) < rangeThreshold)) {
228 client1.addLink(client2);
229 client2.addLink(client1);
230 }
231
232 for (Sensor server : servers)
233 if (server.distance(client1) < rangeThreshold) {
234 client1.addLink(server);
235 server.addLink(client1);
236 }
237 }
238 }
239
240 /**
241 * <p>This method reads a Network from a XML file and builds its corresponding object</p>
242 * <p>The XML file given should have <a href="#xmlFileStructure">this structure</a></p>
243 * @param xmlFilePath Path of the XML file describing the Network to create
244 * @throws java.lang.Exception If the XML file given does not have the structure shown before, or if
245 * a node links to an undefined node, or if a node links to itself
246 */
247 public Network(String xmlFilePath) throws Exception {
248 if (!xmlFilePath.endsWith(".xml"))
249 throw new Exception("Only XML files are accepted");
250 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
251 DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
252 Document doc = docBuilder.parse(new File(xmlFilePath));
253 doc.getDocumentElement().normalize();
254 org.w3c.dom.Node root = doc.getDocumentElement();
255 NodeList nodes = root.getChildNodes();
256
257 clients = new ArrayList<Sensor>();
258 servers = new ArrayList<Sensor>();
259 sensors = new ArrayList<Sensor>();
260 services = new ArrayList<Service>();
261 Sensor.resetId();
262
263 /*
264 * In the first parsing we create every client and server
265 * In the second one, all the links are eestablished
266 */
267 for (int i = 1; i < nodes.getLength(); i++) {
268 org.w3c.dom.Node node = nodes.item(i);
269 if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
270 NamedNodeMap attributes = node.getAttributes();
271 int id = Integer.parseInt(attributes.getNamedItem("id").getNodeValue());
272 double x = Double.parseDouble(attributes.getNamedItem("x").getNodeValue());
273 double y = Double.parseDouble(attributes.getNamedItem("y").getNodeValue());
274 if (node.getNodeName().equals("client")) {
275 Sensor client = newSensor(id, x, y);
276 if (!clients.contains(client)) {
277 clients.add(client);
278 sensors.add(client);
279 }
280 } else if ((node.getNodeName().equals("server")) && (attributes != null)) {
281 Sensor server = newSensor(id,x,y);
282
283 if (!servers.contains(server)) {
284 servers.add(server);
285 sensors.add(server);
286 }
287
288 NodeList nodeChildren = node.getChildNodes();
289 for (int j = 0; j < nodeChildren.getLength(); j++)
290 if (nodeChildren.item(j).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
291 if (nodeChildren.item(j).getNodeName().equals("service")) {
292 double goodness = Double.parseDouble(nodeChildren.item(j).
293 getAttributes().getNamedItem("goodness").getNodeValue());
294 String idService = nodeChildren.item(j).
295 getAttributes().getNamedItem("id").getNodeValue();
296
297 Service service = new Service(idService);
298 if (!services.contains(service))
299 services.add(service);
300 server.addService(service, goodness);
301 } else if ((!nodeChildren.item(j).getNodeName().equals("server")) &&
302 (!nodeChildren.item(j).getNodeName().equals("client")))
303 throw new Exception("Unexpected tag found '"+nodeChildren.item(j).getNodeName()+"' while looking for server "+id+" neighbors and services");
304 }
305 } else
306 throw new Exception("Unexpected tag found '"+node.getNodeName()+"' while looking for servers");
307 }
308 }
309
310 for (int i = 1; i < nodes.getLength(); i++) {
311 org.w3c.dom.Node node = nodes.item(i);
312 if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
313 NamedNodeMap attributes = node.getAttributes();
314 if ((node.getNodeName().equals("client")) && (attributes != null)) {
315 int id = Integer.parseInt(attributes.getNamedItem("id").getNodeValue());
316 Sensor client = null;
317 for (Sensor client_aux : clients)
318 if (client_aux.id() == id)
319 client = client_aux;
320
321 NodeList clientChildren = node.getChildNodes();
322 for (int j = 0; j < clientChildren.getLength(); j++)
323 if (clientChildren.item(j).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
324 if (clientChildren.item(j).getNodeName().equals("server")) {
325 int idServer = Integer.parseInt(clientChildren.item(j).
326 getAttributes().getNamedItem("id").getNodeValue());
327
328 Sensor server = null;
329 for (Sensor server_aux : servers)
330 if (server_aux.id() == idServer)
331 server = server_aux;
332 client.addLink(server);
333 } else if (clientChildren.item(j).getNodeName().equals("client")) {
334 int idClient = Integer.parseInt(clientChildren.item(j).
335 getAttributes().getNamedItem("id").getNodeValue());
336 if (id == idClient)
337 throw new Exception("Client "+id+" has a link to itself");
338 Sensor client_aux = null;
339 for (Sensor client_aux2 : clients)
340 if (client_aux2.id() == idClient)
341 client_aux = client_aux2;
342 client.addLink(client_aux);
343 } else
344 throw new Exception("Unexpected tag found '"+clientChildren.item(i).getNodeName()+"' while looking for client's neighbors");
345
346 } else if ((node.getNodeName().equals("server")) && (attributes != null)) {
347 int id = Integer.parseInt(attributes.getNamedItem("id").getNodeValue());
348
349 Sensor server = null;
350 for (Sensor server_aux : servers)
351 if (server_aux.id() == id)
352 server = server_aux;
353
354 NodeList nodeChildren = node.getChildNodes();
355 for (int j = 0; j < nodeChildren.getLength(); j++)
356 if (nodeChildren.item(j).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
357 if (nodeChildren.item(j).getNodeName().equals("server")) {
358 int idServer = Integer.parseInt(nodeChildren.item(j).
359 getAttributes().getNamedItem("id").getNodeValue());
360 Sensor neighbour = null;
361 for (Sensor server_aux : servers)
362 if (server_aux.id() == idServer)
363 neighbour = server_aux;
364 if (id == idServer)
365 throw new Exception("Server "+id+" has a link to itself");
366
367 server.addLink(neighbour);
368 } else if (nodeChildren.item(j).getNodeName().equals("client")) {
369 int idClient = Integer.parseInt(nodeChildren.item(j).
370 getAttributes().getNamedItem("id").getNodeValue());
371 if (id == idClient)
372 throw new Exception("Client "+id+" has a link to itself");
373 Sensor client = null;
374 for (Sensor client_aux : clients)
375 if (client_aux.id() == idClient)
376 client = client_aux;
377 server.addLink(client);
378 } else if (!nodeChildren.item(j).getNodeName().equals("service"))
379 throw new Exception("Unexpected tag found '"+nodeChildren.item(j).getNodeName()+"' while looking for server "+id+" neighbors and services");
380 }
381 } else
382 throw new Exception("Unexpected tag found '"+node.getNodeName()+"' while looking for servers");
383 }
384 }
385 }
386
387 /**
388 * This method turns every benevolent server in the network into malicious and
389 * counts the number of swapped servers. Then (when every server is malicious)
390 * it randomly selects malicious servers and converts them into benevolent until
391 * the number of benevolent servers is equal to the one before calling this method
392 * @param service Service over what the oscillation is to be carried out
393 */
394 public void oscillate(Service service) {
395 try {
396 int numBenevolentServers = 0;
397 for (Sensor server : servers)
398 if ((server.offersService(service)) && (server.get_goodness(service) >= 0.5)) {
399 numBenevolentServers++;
400 server.set_goodness(service,0.0);
401 }
402
403 double prob = ((double)numBenevolentServers/servers.size());
404 while (numBenevolentServers > 0)
405 for (Sensor server : servers)
406 if ((Math.random() < prob) && (server.offersService(service)) && (server.get_goodness(service)< 0.5)) {
407 server.set_goodness(service,1.0);
408 numBenevolentServers--;
409 if (numBenevolentServers == 0)
410 break;
411 }
412 } catch(Exception ex){ ex.printStackTrace(); }
413 }
414
415 /**
416 * This method creates a new sensor. It must be redefined in each subclass
417 * according to the requirements of each particular trust and reputation
418 * model
419 * @return New created sensor
420 */
421 public abstract Sensor newSensor();
422
423 /**
424 * This method creates a new sensor. It must be redefined in each subclass
425 * according to the requirements of each particular trust and reputation
426 * model
427 * @param id Sensor's identifier
428 * @param x X coordinate of the new sensor
429 * @param y Y coordinate of the new sensor
430 * @return New created sensor
431 */
432 public abstract Sensor newSensor(int id, double x, double y);
433
434 /**
435 * This method resets this network to its initial state
436 */
437 public void reset() {
438 for (Sensor sensor : sensors)
439 sensor.reset();
440 }
441
442 /**
443 * This method establishes every sensor's new neighborhood according to
444 * a new wireless range
445 * @param newRange New wireless range determining every sensor's neighbors
446 */
447 public void setNewNeighbors(double newRange) {
448 double rangeThreshold = newRange*Math.sqrt(2.0)*maxDistance;
449
450 for (Sensor sensor : sensors) {
451 sensor.removeAllNeighbors();
452 for (Sensor sensor2 : sensors)
453 if ((!sensor.equals(sensor2)) && (sensor.distance(sensor2) < rangeThreshold))
454 {
455 sensor.addLink(sensor2);
456 sensor2.addLink(sensor);
457 }
458 }
459 }
460
461 /**
462 * This method writes the current Network into a XML file following
463 * <a href="#xmlFileStructure">this structure</a>
464 * @param fileName Path of the XML file where to write the current Network
465 * @throws Exception If there is any problem when writing to the XML file
466 */
467 public void writeToXMLFile(String fileName) throws Exception {
468 try {
469 if (!fileName.endsWith(".xml"))
470 fileName += ".xml";
471 BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
472
473 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
474 out.write("<wsn>\n");
475 for (Sensor client : clients) {
476 out.write("\t<client id=\""+client.id()
477 +"\" x=\""+(((int)(client.getX()*100))/100.0)
478 +"\" y=\""+(((int)(client.getY()*100))/100.0)
479 +"\">\n");
480 for (Sensor neighbor : client.getNeighbors())
481 if (neighbor.get_numServices() == 0)
482 out.write("\t\t<client id=\""+neighbor.id()+"\"/>\n");
483 else
484 out.write("\t\t<server id=\""+neighbor.id()+"\"/>\n");
485 out.write("\t</client>\n");
486 }
487
488 for (Sensor server : servers) {
489 out.write("\t<server id=\""+server.id()
490 +"\" x=\""+(((int)(server.getX()*100))/100.0)
491 +"\" y=\""+(((int)(server.getY()*100))/100.0)
492 +"\">\n");
493 for (Service service : server.get_services())
494 out.write("\t\t<service id=\""+service.id()+"\" "
495 +"goodness=\""+server.get_goodness(service)+"\""
496 +"/>\n");
497 for (Sensor neighbor : server.getNeighbors())
498 if (neighbor.get_numServices() == 0)
499 out.write("\t\t<client id=\""+neighbor.id()+"\"/>\n");
500 else
501 out.write("\t\t<server id=\""+neighbor.id()+"\"/>\n");
502 out.write("\t</server>\n");
503
504 }
505
506 out.write("</wsn>\n");
507 out.flush();
508 out.close();
509 } catch (Exception ex) {
510 throw new Exception("writeToXMLFile: "+ex);
511 }
512 }
513
514 /**
515 * Prints the whole Network, with all the offered services
516 * @return A string with the whole Network, with all the offered services
517 */
518 @Override
519 public String toString() {
520 String s = "";
521 for (Sensor client : clients)
522 s += "C "+client+"\n";
523 for (Sensor server : servers)
524 s += "S "+server+"\n";
525 return s;
526 }
527
528 /**
529 * Average transmitted distance per sensor of this network
530 * @param searchCondition Condition to be accomplished by the querying sensors
531 * @param requiredService Service requested by the clients
532 * @return Average transmitted distance per sensor of this network
533 */
534 public long get_sensorsTransmittedDistance(ISearchCondition searchCondition, Service requiredService) {
535 long sensorsTransmittedDistance = 0;
536 long numSensors = 0;
537
538 for (Sensor sensor : sensors)
539 if (searchCondition.sensorAcomplishesCondition(sensor) &&
540 reachesQualifiedService(sensor,requiredService)) {
541 sensorsTransmittedDistance += sensor.get_transmittedDistance();
542 numSensors++;
543 }
544
545 if (numSensors != 0)
546 return sensorsTransmittedDistance/numSensors;
547
548 return 0;
549 }
550
551 /**
552 * This method checks if a given sensor can reach any client and any benevolent server offering a given service
553 * @param sensor Sensor to find out whether it can reach a benevolent server or not
554 * @param requiredService Service requested by the clients
555 * @return true if the given sensor can reach any client and any benevolent server offering the given service, false otherwise
556 */
557 protected boolean reachesQualifiedService(Sensor sensor, Service requiredService) {
558 boolean reachableClient = false;
559 boolean reachableBenevolentServer = false;
560 if (sensor.isActive())
561 try {
562 reachableClient = (sensor.get_numServices() == 0);
563 reachableBenevolentServer = ((sensor.get_numServices() > 1) && (sensor.get_goodness(requiredService) > 0.5));
564
565 if (!reachableClient) {
566 Collection<Vector<Sensor>> pathsToClients = sensor.findSensors(new IsClientSearchCondition());
567 reachableClient = ((pathsToClients != null) && (pathsToClients.size() > 0));
568 }
569 if (!reachableBenevolentServer) {
570 Collection<Vector<Sensor>> pathsToServers = sensor.findSensors(new IsServerSearchCondition(requiredService,IsServerSearchCondition.BENEVOLENT_SERVER));
571 reachableBenevolentServer = ((pathsToServers != null) && (pathsToServers.size() > 0));
572 }
573 } catch (Exception ex) { ex.printStackTrace(); }
574
575 return (reachableClient && reachableBenevolentServer);
576 }
577
578 /**
579 * This method returns the sensor with identifier id. If such sensor does not exist, it returns null
580 * @param id Identifier of the sensor to be retrieved
581 * @return The sensor with identifier id. If such sensor does not exist, it returns null
582 */
583 public Sensor getSensor(int id) {
584 if ((sensors == null) || (sensors.isEmpty()))
585 return null;
586
587 for (Sensor sensor : sensors)
588 if (sensor.id() == id)
589 return sensor;
590
591 return null;
592 }
593
594 /**
595 * This method retrieves the set of clients belonging to this network
596 * @return The set of clients belonging to this network
597 */
598 public Collection<Sensor> get_clients() { return clients; }
599
600 /**
601 * This method retrieves the set of servers belonging to this network
602 * @return The set of servers belonging to this network
603 */
604 public Collection<Sensor> get_servers() { return servers; }
605
606 /**
607 * This method retrieves the set of sensors belonging to this network
608 * @return The set of sensors belonging to this network
609 */
610 public Collection<Sensor> get_sensors() { return sensors; }
611
612 /**
613 * This method retrieves the set of services offered by this network
614 * @return The set of services offered by this network
615 */
616 public Collection<Service> get_services() { return services; }
617
618 /**
619 * This method retrieves the total number of sensors composing this network
620 * @return The total number of sensors composing this network
621 */
622 public int get_numSensors() { return sensors.size(); }
623
624 /**
625 * This method retrieves the number of clients belonging to this network
626 * @return The number of clients belonging to this network
627 */
628 public int get_numClients() { return clients.size(); }
629
630 /**
631 * This method retrieves the number of servers belonging to this network
632 * @return The number of servers belonging to this network
633 */
634 public int get_numServers() { return servers.size(); }
635
636 /**
637 * This method retrieves the maximum distance between two nodes in this network
638 * @return The maximum distance between two nodes in this network
639 */
640 public static double get_maxDistance() { return maxDistance; }
641
642 /**
643 * This method establishes if a collusion is to be formed or not in this network
644 * @param collusion Indicates if a collusion is to be formed or not in this network
645 */
646 public void set_collusion(boolean collusion) { Sensor.setCollusion(collusion); }
647
648 /**
649 * This method establishes if the topology of this network is dynamic, because
650 * sensors can sleep or not
651 * @param dynamic Indicates if the topology of this network is dynamic, because
652 * sensors can sleep or not
653 */
654 public void set_dynamic(boolean dynamic) { Sensor.setDynamic(dynamic); }
655 }