Агенты успешно запускаются с использованием основного класса, который инициализирует их внутри основного контейнера JADE. Обмен сообщениями виден в консоли Eclipse (журналы System.out.println подтверждают отправку и получение сообщений REQUEST, PROPOSE и ACCEPT_PROPOSAL).
Графический интерфейс DFService (Directory Facilitator) показывает агенты Nettoyeur, что означает, что они правильно зарегистрированы. Переговоры между агентами работают правильно, как видно из журналов консоли. Агент Sniffer не отображает сообщения, хотя агенты нормально общаются в консоли.
Перезапуск агента Sniffer и повторное добавление агентов не помогли
Код основного класса (инициализация агента):
Код: Выделить всё
package TP2;
import jade.core.Runtime;
import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.wrapper.AgentContainer;
import jade.wrapper.AgentController;
import jade.wrapper.StaleProxyException;
public class Main {
public static void main(String[] args) {
Runtime rt = Runtime.instance();
Profile p = new ProfileImpl("localhost", 1099, null);
p.setParameter(Profile.GUI, "true"); // Enable GUI to show RMA
AgentContainer container = rt.createMainContainer(p);
try {
System.out.println("📌 Creating agents...");
AgentController pollueur = container.createNewAgent("Pollueur", TP2.PollueurAgent.class.getName(), null);
AgentController nettoyeur1 = container.createNewAgent("Nettoyeur1", TP2.NettoyeurAgent.class.getName(), null);
AgentController nettoyeur2 = container.createNewAgent("Nettoyeur2", TP2.NettoyeurAgent.class.getName(), null);
AgentController nettoyeur3 = container.createNewAgent("Nettoyeur3", TP2.NettoyeurAgent.class.getName(), null);
pollueur.start();
nettoyeur1.start();
nettoyeur2.start();
nettoyeur3.start();
System.out.println("✅ Agents started successfully.");
} catch (StaleProxyException e) {
System.err.println("❌ Error: Could not start JADE agents!");
e.printStackTrace();
}
}
}
Код: Выделить всё
package TP2;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import java.util.Random;
import java.util.HashMap;
import java.util.Map;
public class PollueurAgent extends Agent {
private static final int SIZE = 10;
private static char[][] environment = new char[SIZE][SIZE];
private Random random = new Random();
private Map proposals = new HashMap();
private Map prices = new HashMap();
private String bestCleaner = null;
private int bestArrivalTime = Integer.MAX_VALUE;
private int targetX, targetY;
private int negotiationRound = 0;
protected void setup() {
System.out.println("Agent Pollueur démarré...");
// Register PollueurAgent in DF Service
DFAgentDescription dfd = new DFAgentDescription();
dfd.setName(getAID());
ServiceDescription sd = new ServiceDescription();
sd.setType("pollution-service");
sd.setName(getLocalName());
dfd.addServices(sd);
try {
DFService.register(this, dfd);
System.out.println(getLocalName() + " enregistré dans le DF.");
} catch (FIPAException e) {
e.printStackTrace();
}
initializeEnvironment();
displayEnvironment();
pollute();
addBehaviour(new ReceiveOffers());
}
private void initializeEnvironment() {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
environment[i][j] = '.';
}
}
}
static void displayEnvironment() {
System.out.println("État actuel de l'environnement :");
for (char[] row : environment) {
for (char cell : row) {
System.out.print(cell + " ");
}
System.out.println();
}
System.out.println();
}
private void pollute() {
targetX = random.nextInt(SIZE);
targetY = random.nextInt(SIZE);
environment[targetX][targetY] = 'X';
System.out.println("Pollution à la case (" + targetX + "," + targetY + ")");
ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
msg.setContent(targetX + "," + targetY);
msg.addReceiver(new jade.core.AID("Nettoyeur1", jade.core.AID.ISLOCALNAME));
msg.addReceiver(new jade.core.AID("Nettoyeur2", jade.core.AID.ISLOCALNAME));
msg.addReceiver(new jade.core.AID("Nettoyeur3", jade.core.AID.ISLOCALNAME));
send(msg);
displayEnvironment();
}
public static void cleanCell(int x, int y) {
environment[x][y] = '.';
}
private class ReceiveOffers extends CyclicBehaviour {
public void action() {
ACLMessage msg = receive();
if (msg != null && msg.getPerformative() == ACLMessage.PROPOSE) {
String sender = msg.getSender().getLocalName();
String[] content = msg.getContent().split(",");
try {
int price = Integer.parseInt(content[0]); // Fixed parsing
int arrivalTime = Integer.parseInt(content[1]);
proposals.put(sender, arrivalTime);
prices.put(sender, price);
if (arrivalTime < bestArrivalTime) {
bestArrivalTime = arrivalTime;
bestCleaner = sender;
}
if (proposals.size() == 3) {
negotiateOrAccept();
}
} catch (NumberFormatException e) {
System.err.println("Error parsing message from " + sender + ": " + msg.getContent());
}
} else {
block();
}
}
}
private void negotiateOrAccept() {
if (bestCleaner != null) {
int bestPrice = prices.get(bestCleaner);
if (bestPrice > 10 && negotiationRound < 2) {
negotiationRound++;
System.out.println("Pollueur négocie avec " + bestCleaner + " pour réduire le prix de " + bestPrice);
ACLMessage negotiateMsg = new ACLMessage(ACLMessage.PROPOSE);
negotiateMsg.addReceiver(new jade.core.AID(bestCleaner, jade.core.AID.ISLOCALNAME));
negotiateMsg.setContent((bestPrice - 5) + "," + bestArrivalTime);
send(negotiateMsg);
} else {
ACLMessage acceptMsg = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL);
acceptMsg.addReceiver(new jade.core.AID(bestCleaner, jade.core.AID.ISLOCALNAME));
acceptMsg.setContent(targetX + "," + targetY);
send(acceptMsg);
System.out.println("Pollueur sélectionne " + bestCleaner + " pour nettoyer la case (" + targetX + "," + targetY + ") au prix de " + bestPrice);
proposals.clear();
prices.clear();
bestCleaner = null;
bestArrivalTime = Integer.MAX_VALUE;
negotiationRound = 0;
}
}
}
}
Код: Выделить всё
package TP2;
import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import java.util.Random;
public class NettoyeurAgent extends Agent {
private int price;
private int arrivalTime;
protected void setup() {
price = new Random().nextInt(50) + 10;
arrivalTime = new Random().nextInt(10) + 1;
System.out.println("Agent " + getLocalName() + " démarré avec prix: " + price + " et temps d'arrivée: " + arrivalTime);
// Register agent in DFService (Yellow Pages)
DFAgentDescription dfd = new DFAgentDescription();
dfd.setName(getAID());
ServiceDescription sd = new ServiceDescription();
sd.setType("cleaning-service");
sd.setName(getLocalName());
dfd.addServices(sd);
try {
DFService.register(this, dfd);
} catch (FIPAException e) {
e.printStackTrace();
}
addBehaviour(new CyclicBehaviour(this) {
public void action() {
ACLMessage msg = receive();
if (msg != null) {
switch (msg.getPerformative()) {
case ACLMessage.REQUEST:
ACLMessage reply = msg.createReply();
reply.setPerformative(ACLMessage.PROPOSE);
reply.setContent(price + "," + arrivalTime);
send(reply);
System.out.println("📩 " + getLocalName() + " répond avec: " + price + "," + arrivalTime);
break;
case ACLMessage.PROPOSE:
int newPrice = Integer.parseInt(msg.getContent().split(",")[0]);
System.out.println(getLocalName() + " négocie et accepte " + newPrice);
price = newPrice;
ACLMessage counterOffer = msg.createReply();
counterOffer.setPerformative(ACLMessage.PROPOSE);
counterOffer.setContent(price + "," + arrivalTime);
send(counterOffer);
break;
case ACLMessage.ACCEPT_PROPOSAL:
String[] coordinates = msg.getContent().split(",");
int x = Integer.parseInt(coordinates[0]);
int y = Integer.parseInt(coordinates[1]);
System.out.println(getLocalName() + " nettoie la case (" + x + "," + y + ")");
PollueurAgent.cleanCell(x, y);
PollueurAgent.displayEnvironment();
break;
}
} else {
block();
}
}
});
}
}