package iamrescue.communication.scenario; import iamrescue.communication.messages.MessageChannel; import iamrescue.communication.messages.MessageChannelType; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.collections15.Factory; import org.apache.commons.collections15.Transformer; import org.apache.commons.lang.Validate; import rescuecore2.standard.entities.StandardEntityURN; import edu.uci.ics.jung.algorithms.flows.EdmondsKarpMaxFlow; import edu.uci.ics.jung.algorithms.shortestpath.DijkstraDistance; import edu.uci.ics.jung.graph.DirectedSparseGraph; public class CommunicationGraph { private DirectedSparseGraph<CommunicationGraphVertex, CommunicationGraphEdge> graph = new DirectedSparseGraph<CommunicationGraphVertex, CommunicationGraphEdge>(); private EnumMap<StandardEntityURN, AgentReceivingVertex> receivingVertices = new EnumMap<StandardEntityURN, AgentReceivingVertex>( StandardEntityURN.class); private EnumMap<StandardEntityURN, AgentSendingVertex> sendingVertices = new EnumMap<StandardEntityURN, AgentSendingVertex>( StandardEntityURN.class); private Set<StandardEntityURN> platoons = new HashSet<StandardEntityURN>(); private Set<StandardEntityURN> centres = new HashSet<StandardEntityURN>(); private Map<MessageChannel, MessageChannelVertex> channelReceivingVertices = new HashMap<MessageChannel, MessageChannelVertex>(); private Map<MessageChannel, MessageChannelVertex> channelSendingVertices = new HashMap<MessageChannel, MessageChannelVertex>(); private Transformer<CommunicationGraphEdge, Number> transformer; public Collection<StandardEntityURN> getPlatoons() { return platoons; } public Collection<StandardEntityURN> getCentres() { return centres; } public Collection<MessageChannel> getChannels() { return channelReceivingVertices.keySet(); } public void addChannel(MessageChannel channel) { Validate.isTrue(channel.getType() == MessageChannelType.RADIO); MessageChannelVertex sendingVertex = new MessageChannelVertex(channel); MessageChannelVertex receivingVertex = new MessageChannelVertex(channel); channelReceivingVertices.put(channel, receivingVertex); channelSendingVertices.put(channel, sendingVertex); graph.addVertex(sendingVertex); graph.addVertex(receivingVertex); graph.addEdge(new IntraChannelEdge(channel.getBandwidth()), receivingVertex, sendingVertex); } public void addPlatoon(StandardEntityURN type, int number) { addAgentVertices(type, number); platoons.add(type); } public void addCentre(StandardEntityURN type, int number) { addAgentVertices(type, number); centres.add(type); } private void addAgentVertices(StandardEntityURN type, int number) { AgentSendingVertex sendingVertex = new AgentSendingVertex(type, number); AgentReceivingVertex receivingVertex = new AgentReceivingVertex(type, number); sendingVertices.put(type, sendingVertex); receivingVertices.put(type, receivingVertex); graph.addVertex(sendingVertex); graph.addVertex(receivingVertex); graph.addEdge(new IntraAgentEdge(), receivingVertex, sendingVertex); } // public void addIncomingChannel(StandardEntityURN type, // MessageChannel channel) { // graph.addEdge(new IncomingMessageChannelAssignment(), // getChannelVertex(channel), getAgentReceivingVertex(type)); // } // // public void addOutgoingChannel(StandardEntityURN type, // MessageChannel channel, int bytes) { // graph.addEdge(new OutgoingMessageChannelAssignment(bytes), // getAgentSendingVertex(type), getChannelVertex(channel)); // } public int getMaximumDelay() { Collection<StandardEntityURN> platoons = getPlatoons(); DijkstraDistance<CommunicationGraphVertex, CommunicationGraphEdge> distance = new DijkstraDistance<CommunicationGraphVertex, CommunicationGraphEdge>( graph, new Transformer<CommunicationGraphEdge, Double>() { public Double transform(CommunicationGraphEdge input) { if (input instanceof OutgoingMessageChannelAssignment) return 1.0; return 0.0; } }); int maxDistance = 0; for (StandardEntityURN platoon1 : platoons) { for (StandardEntityURN platoon2 : platoons) { Number value = distance.getDistance( getAgentSendingVertex(platoon1), getAgentReceivingVertex(platoon2)); if (value == null) { System.out.println("Not connected"); continue; } maxDistance = Math.max(maxDistance, value.intValue()); } } return maxDistance; } private CommunicationGraphVertex getSendingChannelVertex( MessageChannel channel) { Validate.isTrue(channelSendingVertices.containsKey(channel)); return channelSendingVertices.get(channel); } private CommunicationGraphVertex getReceivingChannelVertex( MessageChannel channel) { Validate.isTrue(channelReceivingVertices.containsKey(channel)); return channelReceivingVertices.get(channel); } private AgentSendingVertex getAgentSendingVertex(StandardEntityURN type) { AgentSendingVertex agentSendingVertex = sendingVertices.get(type); Validate.notNull(agentSendingVertex); return agentSendingVertex; } private AgentReceivingVertex getAgentReceivingVertex(StandardEntityURN type) { AgentReceivingVertex agentReceivingVertex = receivingVertices.get(type); Validate.notNull(agentReceivingVertex); return agentReceivingVertex; } public Collection<MessageChannel> getIncomingMessageChannels( StandardEntityURN type) { AgentVertex agentVertex = getAgentReceivingVertex(type); Collection<CommunicationGraphVertex> predecessors = graph .getPredecessors(agentVertex); return getChannels(predecessors); } public int getAllocatedBandWidth(MessageChannel channel) { MessageChannelVertex messageChannelVertex = channelReceivingVertices .get(channel); Collection<CommunicationGraphEdge> inEdges = graph .getInEdges(messageChannelVertex); int allocatedBandwidth = 0; for (CommunicationGraphEdge assignment : inEdges) { allocatedBandwidth += assignment.getFlow(); } return allocatedBandwidth; } private Collection<MessageChannel> getChannels( Collection<CommunicationGraphVertex> vertices) { Collection<MessageChannel> result = new ArrayList<MessageChannel>(); for (CommunicationGraphVertex predecessor : vertices) { MessageChannelVertex vertex = (MessageChannelVertex) predecessor; result.add(vertex.getChannel()); } return result; } public Collection<MessageChannel> getOutgoingMessageChannels( StandardEntityURN type) { AgentVertex agentVertex = getAgentSendingVertex(type); Collection<CommunicationGraphVertex> successors = graph .getSuccessors(agentVertex); return getChannels(successors); } public int getIncomingChannelCount(StandardEntityURN type) { return graph.getPredecessorCount(getAgentReceivingVertex(type)); } public int getOutgoingChannelCount(StandardEntityURN type) { return graph.getSuccessorCount(getAgentSendingVertex(type)); } public int computeMaximumFlow() { for (MessageChannelVertex vertex : channelSendingVertices.values()) { for (AgentReceivingVertex agentVertex : receivingVertices.values()) { graph.addEdge(new IncomingMessageChannelAssignment(), vertex, agentVertex); } } for (AgentSendingVertex agentVertex : sendingVertices.values()) { for (MessageChannelVertex vertex : channelReceivingVertices .values()) { graph.addEdge(new OutgoingMessageChannelAssignment(), agentVertex, vertex); } } SourceSinkVertex source = new SourceSinkVertex(); graph.addVertex(source); SourceSinkVertex sink = new SourceSinkVertex(); graph.addVertex(sink); for (StandardEntityURN platoon : platoons) { graph.addEdge(new SourceSinkEdge(), source, getAgentSendingVertex(platoon)); } for (StandardEntityURN platoon : platoons) { graph.addEdge(new SourceSinkEdge(), getAgentReceivingVertex(platoon), sink); } HashMap<CommunicationGraphEdge, Number> flows = new HashMap<CommunicationGraphEdge, Number>(); EdmondsKarpMaxFlow<CommunicationGraphVertex, CommunicationGraphEdge> edmondsKarpMaxFlow = new EdmondsKarpMaxFlow<CommunicationGraphVertex, CommunicationGraphEdge>( graph, source, sink, getEdgeCapacityTransformer(), flows, new Factory<CommunicationGraphEdge>() { @Override public CommunicationGraphEdge create() { return new IncomingMessageChannelAssignment(); } }); edmondsKarpMaxFlow.evaluate(); for (CommunicationGraphEdge edge : flows.keySet()) { edge.setAssignedFlow(flows.get(edge).intValue()); } return edmondsKarpMaxFlow.getMaxFlow(); } public int getMaximumFlow(StandardEntityURN source, StandardEntityURN sink) { EdmondsKarpMaxFlow<CommunicationGraphVertex, CommunicationGraphEdge> edmondsKarpMaxFlow = new EdmondsKarpMaxFlow<CommunicationGraphVertex, CommunicationGraphEdge>( graph, getAgentSendingVertex(source), getAgentReceivingVertex(sink), getEdgeCapacityTransformer(), new HashMap<CommunicationGraphEdge, Number>(), new Factory<CommunicationGraphEdge>() { @Override public CommunicationGraphEdge create() { return new IncomingMessageChannelAssignment(); } }); edmondsKarpMaxFlow.evaluate(); return edmondsKarpMaxFlow.getMaxFlow(); } private Transformer<CommunicationGraphEdge, Number> getEdgeCapacityTransformer() { if (transformer == null) { transformer = new Transformer<CommunicationGraphEdge, Number>() { @Override public Number transform(CommunicationGraphEdge assignment) { return assignment.getMaximumBandwidth(); } }; } return transformer; } /*public static void main(String[] args) { MessageChannel channel1 = MessageChannel.get(10, MessageChannelType.RADIO); channel1.setBandwidth(40); MessageChannel channel2 = MessageChannel.get(2, MessageChannelType.RADIO); channel2.setBandwidth(30); MessageChannel channel3 = MessageChannel.get(3, MessageChannelType.RADIO); channel3.setBandwidth(100); MessageChannel channel4 = MessageChannel.get(5, MessageChannelType.RADIO); channel4.setBandwidth(60); CommunicationGraph communicationGraph = new CommunicationGraph(); communicationGraph.addChannel(channel1); communicationGraph.addChannel(channel2); // communicationGraph.addChannel(channel3); // communicationGraph.addChannel(channel4); communicationGraph.addCentre(StandardEntityURN.AMBULANCE_CENTRE, 5); communicationGraph.addPlatoon(StandardEntityURN.FIRE_BRIGADE, 20); // communicationGraph.addCentre(StandardEntityURN.FIRE_STATION, 1); // // FB <1-4> FS <2-3> AC // communicationGraph.addOutgoingChannel(StandardEntityURN.FIRE_BRIGADE, // channel1, 53); // communicationGraph.addIncomingChannel(StandardEntityURN.FIRE_STATION, // channel1); // // communicationGraph.addOutgoingChannel(StandardEntityURN.FIRE_STATION, // channel2, 85); // communicationGraph.addIncomingChannel( // StandardEntityURN.AMBULANCE_CENTRE, channel2); // // communicationGraph.addOutgoingChannel( // StandardEntityURN.AMBULANCE_CENTRE, channel3, 20); // communicationGraph.addIncomingChannel(StandardEntityURN.FIRE_STATION, // channel3); // // communicationGraph.addOutgoingChannel(StandardEntityURN.FIRE_STATION, // channel4, 15); // communicationGraph.addIncomingChannel(StandardEntityURN.FIRE_BRIGADE, // channel4); System.out .println(communicationGraph .getIncomingMessageChannels(StandardEntityURN.AMBULANCE_CENTRE)); // System.out.println(communicationGraph.getAllocatedBandWidth(channel)); System.out.println(communicationGraph.getMaximumFlow( StandardEntityURN.FIRE_BRIGADE, StandardEntityURN.AMBULANCE_CENTRE)); System.out.println(communicationGraph.getMaximumFlow( StandardEntityURN.AMBULANCE_CENTRE, StandardEntityURN.FIRE_BRIGADE)); System.out.println(communicationGraph.computeMaximumFlow()); System.out.println(communicationGraph.getMaximumDelay()); CommunicationGraphGUI.show(communicationGraph); } public static void main1(String[] args) { MessageChannel channel1 = MessageChannel.get(10, MessageChannelType.RADIO); channel1.setBandwidth(30); CommunicationGraph communicationGraph = new CommunicationGraph(); communicationGraph.addChannel(channel1); communicationGraph.addPlatoon(StandardEntityURN.AMBULANCE_CENTRE, 5); // communicationGraph.addIncomingChannel( // StandardEntityURN.AMBULANCE_CENTRE, channel1); // // communicationGraph.addOutgoingChannel( // StandardEntityURN.AMBULANCE_CENTRE, channel1, 20); System.out .println(communicationGraph .getIncomingMessageChannels(StandardEntityURN.AMBULANCE_CENTRE)); // System.out.println(communicationGraph.getAllocatedBandWidth(channel)); System.out.println(communicationGraph.getMaximumFlow( StandardEntityURN.AMBULANCE_CENTRE, StandardEntityURN.AMBULANCE_CENTRE)); System.out.println(communicationGraph.getMaximumDelay()); System.out.println(communicationGraph.computeMaximumFlow()); CommunicationGraphGUI.show(communicationGraph); }*/ public DirectedSparseGraph<CommunicationGraphVertex, CommunicationGraphEdge> getGraph() { return graph; } public void clearAllocations() { Collection<CommunicationGraphEdge> edges = graph.getEdges(); Collection<CommunicationGraphEdge> edgesToRemove = new ArrayList<CommunicationGraphEdge>(); for (CommunicationGraphEdge edge : edges) { if (!(edge instanceof IntraAgentEdge || edge instanceof IntraChannelEdge)) { edgesToRemove.add(edge); } } for (CommunicationGraphEdge edge : edgesToRemove) { graph.removeEdge(edge); } Validate.isTrue(graph.getEdgeCount() == receivingVertices.size()); } public int getSenderCount(MessageChannel channel) { return graph.getPredecessorCount(getReceivingChannelVertex(channel)); } public int getReceiverCount(MessageChannel channel) { return graph.getSuccessorCount(getSendingChannelVertex(channel)); } }