package iamrescue.communication.scenario;
import iamrescue.communication.ISimulationCommunicationConfiguration;
import iamrescue.communication.messages.MessageChannel;
import iamrescue.communication.messages.MessageChannelType;
import iamrescue.util.CombinatorialIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.Validate;
import rescuecore2.standard.entities.StandardEntityURN;
public class ChannelAllocationAlgorithm {
private ISimulationCommunicationConfiguration configuration;
public ChannelAllocationAlgorithm(
ISimulationCommunicationConfiguration configuration) {
this.configuration = configuration;
}
public boolean validate(CommunicationGraph graph) {
Collection<StandardEntityURN> centres = graph.getCentres();
// check centres are listening to an allowable number of channels
for (StandardEntityURN type : centres) {
int incomingChannelCount = graph.getIncomingChannelCount(type);
if (incomingChannelCount != configuration
.getMaxListenChannelCountCentre()) {
System.out.println("centre has wrong number of channels "
+ incomingChannelCount);
return false;
}
}
Collection<StandardEntityURN> platoons = graph.getPlatoons();
// check platoons are listening to an allowable number of channels
for (StandardEntityURN type : platoons) {
int incomingChannelCount = graph.getIncomingChannelCount(type);
if (incomingChannelCount != configuration
.getMaxListenChannelCountPlatoon()) {
System.out.println("platoon has too many channels "
+ incomingChannelCount);
return false;
}
}
for (MessageChannel channel : graph.getChannels()) {
if (graph.getSenderCount(channel) > 0) {
if (graph.getReceiverCount(channel) == 0) {
System.out.println("Channel " + channel
+ " has senders but no receivers");
return false;
}
}
if (graph.getReceiverCount(channel) > 0) {
if (graph.getSenderCount(channel) == 0) {
System.out.println("Channel " + channel
+ " has receivers but no senders");
return false;
}
}
int allocatedBandWidth = graph.getAllocatedBandWidth(channel);
if (allocatedBandWidth > channel.getBandwidth()) {
System.out.println(channel.getBandwidth());
System.out.println(allocatedBandWidth);
return false;
}
}
return true;
}
public void run() {
// for each incoming combination
List<MessageChannel> channels = configuration.getChannels();
List<StandardEntityURN> centres = new ArrayList<StandardEntityURN>(
configuration.getCentresByType().keySet());
List<StandardEntityURN> platoons = new ArrayList<StandardEntityURN>(
configuration.getPlatoonsByType().keySet());
List<StandardEntityURN> agents = new ArrayList<StandardEntityURN>();
agents.addAll(centres);
agents.addAll(platoons);
int totalOutgoingEdges = centres.size()
* configuration.getMaxListenChannelCountCentre()
+ platoons.size()
* configuration.getMaxListenChannelCountPlatoon();
CommunicationGraph graph = new CommunicationGraph();
for (MessageChannel channel : channels) {
if (channel.getType() != MessageChannelType.VOICE)
graph.addChannel(channel);
}
for (StandardEntityURN platoon : platoons) {
graph.addPlatoon(platoon, configuration.getAgentsByType().get(
platoon).size());
}
Validate.isTrue(graph.getPlatoons().containsAll(platoons));
Validate.isTrue(platoons.containsAll(graph.getPlatoons()));
for (StandardEntityURN centre : centres) {
graph.addCentre(centre, configuration.getCentresByType()
.get(centre).size());
}
Validate.isTrue(graph.getCentres().containsAll(centres));
Validate.isTrue(centres.containsAll(graph.getCentres()));
CombinatorialIterator<MessageChannel> incoming = new CombinatorialIterator<MessageChannel>(
channels, totalOutgoingEdges);
System.out.println(totalOutgoingEdges);
for (List<MessageChannel> incomingChannels : incoming) {
graph.clearAllocations();
System.out.println(incomingChannels.size());
Iterator<MessageChannel> iterator = incomingChannels.iterator();
Map<StandardEntityURN, Set<MessageChannel>> assignment = getAssignment(
iterator, centres, platoons);
if (assignment == null) {
System.out.println(incomingChannels);
System.out.println(assignment);
continue;
}
// for (StandardEntityURN type : assignment.keySet()) {
// for (MessageChannel channel : assignment.get(type)) {
// graph.addIncomingChannel(type, channel);
// }
// }
// CommunicationGraphGUI.show(graph);
Validate.isTrue(!iterator.hasNext());
if (!validate(graph)) {
for (StandardEntityURN urn : platoons) {
System.out.println(graph.getIncomingChannelCount(urn));
}
for (StandardEntityURN urn : centres) {
System.out.println(graph.getIncomingChannelCount(urn));
}
CommunicationGraphGUI.show(graph);
}
Validate.isTrue(validate(graph));
}
// greedily maximise minimum flow
}
private Map<StandardEntityURN, Set<MessageChannel>> getAssignment(
Iterator<MessageChannel> iterator, List<StandardEntityURN> centres,
List<StandardEntityURN> platoons) {
Map<StandardEntityURN, Set<MessageChannel>> result = new HashMap<StandardEntityURN, Set<MessageChannel>>();
for (int i = 0; i < centres.size(); i++) {
result.put(centres.get(i), new HashSet<MessageChannel>());
for (int j = 0; j < configuration.getMaxListenChannelCountCentre(); j++) {
result.get(centres.get(i)).add(iterator.next());
}
if (result.get(centres.get(i)).size() != configuration
.getMaxListenChannelCountCentre())
return null;
}
for (int i = 0; i < platoons.size(); i++) {
result.put(platoons.get(i), new HashSet<MessageChannel>());
for (int j = 0; j < configuration.getMaxListenChannelCountPlatoon(); j++) {
result.get(platoons.get(i)).add(iterator.next());
}
if (result.get(platoons.get(i)).size() != configuration
.getMaxListenChannelCountPlatoon())
return null;
}
return result;
}
public static void main(String[] args) {
// ISimulationCommunicationConfiguration configuration = new
// TestCommunicationScenarioDetector()
// .createConfiguration(StandardEntityURN.AMBULANCE_CENTRE);
//
// ChannelAllocationAlgorithm channelAllocationAlgorithm = new
// ChannelAllocationAlgorithm(
// configuration);
//
// channelAllocationAlgorithm.run();
}
}