分布式之agent

Agent的简单运用,实现卖旗子代理。这个代码实现的要求如下,这个做了很久了,突然想到,才整理出来贴出来。没法翻译,将就着看吧,看英文多了,其实觉得还不错啦。

There is a buyer who wants to buy a specific flag from one or two seller agents who are trying to offer the best (lowest) price. You are to model this situation in JADE.

The Buyer:

Each buyer tells what kind of flag he wants to buy as a command line argument and periodically requests all known seller agents to provide an offer. As soon as an offer is received the buyer agent accepts it and issues a purchase order.

If it more than one seller agent provides an offer the buyer agent accepts the lowest price. Having bought the flag the buyer agent terminates.

The two Sellers:

Each seller agent has a minimal GUI by means of which a user (you) can insert a name of a flag and the associated price of the flag for sale. Example: Japanese flag, 100 . This is to inform the application what the seller has for sale, Seller agents continuously wait for request from buyer agents.

When asked to provide an offer for a specific flag (i.e this is when your program starts) they check if the requested flag is in store and in this case reply with the price. Otherwise they refuse. When they receive a purchase order they serve it and remove the request book from their catalogue

The sellers are not aware of each other. In short this means that the buyer asks the two sellers which of them has the lowest price on one specific flag. The buyer will immediately accept the proposal from the sellers with the lowest bid.

 

    整个的实现是用JADE and NetBeans,建立了四个agent 类。

这个是买旗子的agent

package sellflag;

import jade.core.Agent;
import jade.core.AID;
import jade.core.behaviours.*;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;

public class FlagBuyerAgent extends Agent {
  // The title of the book to buy
  private String targetflag;
  // The list of known seller agents
  private AID[] sellerAgents;//to store all the selleragents in DF

    private FlagBuyerGui mybuyerGui;
  // Put agent initializations here
    @Override
 protected void setup()
    {
   // Printout a welcome message
   System.out.println("Hello! Buyer-agent "+getAID().getName()+" is ready.");

    // Get the title of the book to buy as a start-up argument

          mybuyerGui = new FlagBuyerGui(this);
          mybuyerGui.show();//buyer enter the flag name
   // Get the title of the book to buy as a start-up argument
  // if (true) {
  // Add a TickerBehaviour that schedules a request to seller agents every minute
     addBehaviour(new TickerBehaviour(this, 60000)
            {//wait for 1 minute to request service

       protected void onTick()
              {//from here we have gotten the targetflag form the GUI, if it is null ,one minute later the buyeragent terminates
                  if(targetflag!=null)
                  {
       System.out.println("Trying to buy "+targetflag);
                            // Update the list of seller agents
                            DFAgentDescription template = new DFAgentDescription();
                            ServiceDescription sd = new ServiceDescription();
                            sd.setType("flag-selling");
                            template.addServices(sd);
                            try {
                        DFAgentDescription[] result = DFService.search(myAgent, template); //return all the agents which sell the book
                        System.out.println("Found the following seller agents:");
                             sellerAgents = new AID[result.length];//initialize selleragents array according to result length;
                             for (int i = 0; i < result.length; ++i)
                                {
                                sellerAgents[i] = result[i].getName();
                    System.out.println(sellerAgents[i].getName());//why dont we use result.getname() to print;
                                }
                                }
                            catch (FIPAException fe)
                               {
                                fe.printStackTrace();
                               }
         
                             // Perform the request
                      myAgent.addBehaviour(new RequestPerformer());
                }
                 else
                  {
                             // Make the agent terminate
                      System.out.println("No target flag title specified");
                      //doDelete();
                   }
       }
     } );
   }
    public void getFlagtitle(final String title) {
    addBehaviour(new OneShotBehaviour() {
      public void action() {
       targetflag= title;

      }
    } );
  }

  // Put agent clean-up operations here
  protected void takeDown() {
       mybuyerGui.dispose();//dispose the gui as well
    // Printout a dismissal message
    System.out.println("Buyer-agent "+getAID().getName()+" terminating.");
  }
 
 /**
    Inner class RequestPerformer.
    This is the behaviour used by Book-buyer agents to request seller
    agents the target book.
  */
 private class RequestPerformer extends Behaviour {
   private AID bestSeller; // The agent who provides the best offer
   private int bestPrice;  // The best offered price
   private int repliesCnt = 0; // The counter of replies from seller agents
   private MessageTemplate mt; // The template to receive replies
   private int step = 0;
 
   public void action() {
     switch (step) {
     case 0:
       // Send the cfp to all sellers
       ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
       for (int i = 0; i < sellerAgents.length; ++i) {
         cfp.addReceiver(sellerAgents[i]);
       }
       cfp.setContent(targetflag);
       cfp.setConversationId("flag-trade");
       cfp.setReplyWith("cfp"+System.currentTimeMillis()); // Unique value
       myAgent.send(cfp);
       // Prepare the template to get proposals
       mt = MessageTemplate.and(MessageTemplate.MatchConversationId("flag-trade"),
                                MessageTemplate.MatchInReplyTo(cfp.getReplyWith()));
       step = 1;
       break;
     case 1:
       // Receive all proposals/refusals from seller agents
       ACLMessage reply = myAgent.receive(mt);
       if (reply != null) {
         // Reply received
         if (reply.getPerformative() == ACLMessage.PROPOSE) {
           // This is an offer
           int price = Integer.parseInt(reply.getContent());
           if (bestSeller == null || price < bestPrice) {
             // This is the best offer at present
             bestPrice = price;
             bestSeller = reply.getSender();
           }
         }
         repliesCnt++;
         if (repliesCnt >= sellerAgents.length) {
           // We received all replies
           step = 2;
         }
       }
       else {
         block();
       }
       break;
     case 2:
       // Send the purchase order to the seller that provided the best offer
       ACLMessage order = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL);
        order.addReceiver(bestSeller);
       order.setContent(targetflag);
       order.setConversationId("flag-trade");
       order.setReplyWith("order"+System.currentTimeMillis());
       myAgent.send(order);
       // Prepare the template to get the purchase order reply
       mt = MessageTemplate.and(MessageTemplate.MatchConversationId("flag-trade"),
                                MessageTemplate.MatchInReplyTo(order.getReplyWith()));
       step = 3;
       break;
     case 3:     
       // Receive the purchase order reply
       reply = myAgent.receive(mt);
       if (reply != null) {
         // Purchase order reply received
         if (reply.getPerformative() == ACLMessage.INFORM) {
           // Purchase successful. We can terminate
           System.out.println(targetflag+" successfully purchased from agent "+reply.getSender().getName());
           System.out.println("Price = "+bestPrice);
           myAgent.doDelete();
         }
         else {
           System.out.println("Attempt failed: requested flag already sold.");
         }
          
         step = 4;
       }
       else {
         block();
       }
       break;
     }       
   }
 
   public boolean done() {
    if (step == 2 && bestSeller == null) {
     System.out.println("Attempt failed: "+targetflag+" not available for sale");
    }
     return ((step == 2 && bestSeller == null) || step == 4);
   }
 }  // End of inner class RequestPerformer
}

第二个类是旗子卖家agent类

package sellflag;

import jade.core.Agent;
import jade.core.behaviours.*;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;

import java.util.*;

public class FlagSellerAgent extends Agent {
  // The catalogue of books for sale (maps the title of a book to its price)
  private Hashtable catalogue;
  // The GUI by means of which the user can add books in the catalogue
  private FlagSellerGui myGui;

  // Put agent initializations here
  protected void setup() {
    // Create the catalogue
    catalogue = new Hashtable();

    // Create and show the GUI
    myGui = new FlagSellerGui(this);
    myGui.show();

    // Register the book-selling service in the yellow pages
    DFAgentDescription dfd = new DFAgentDescription();
    dfd.setName(getAID());
    ServiceDescription sd = new ServiceDescription();
    sd.setType("flag-selling");
    sd.setName("JADE-flag-trading");
    dfd.addServices(sd);
    try {
      DFService.register(this, dfd);
    }
    catch (FIPAException fe) {
      fe.printStackTrace();
    }
   
    // Add the behaviour serving queries from buyer agents
    addBehaviour(new OfferRequestsServer());

    // Add the behaviour serving purchase orders from buyer agents
    addBehaviour(new PurchaseOrdersServer());
  }

  // Put agent clean-up operations here
  protected void takeDown() {
    // Deregister from the yellow pages
    try {
      DFService.deregister(this);
    }
    catch (FIPAException fe) {
      fe.printStackTrace();
    }
   // Close the GUI
   myGui.dispose();
    // Printout a dismissal message
    System.out.println("Seller-agent "+getAID().getName()+" terminating.");
  }

  /**
     This is invoked by the GUI when the user adds a new book for sale
   */
  public void updateCatalogue(final String title, final int price) {
    addBehaviour(new OneShotBehaviour() {
      public void action() {
        catalogue.put(title, new Integer(price));
        System.out.println(title+" inserted into catalogue. Price = "+price);
      }
    } );
  }
 
 /**
    Inner class OfferRequestsServer.
    This is the behaviour used by Book-seller agents to serve incoming requests
    for offer from buyer agents.
    If the requested book is in the local catalogue the seller agent replies
    with a PROPOSE message specifying the price. Otherwise a REFUSE message is
    sent back.
  */
 private class OfferRequestsServer extends CyclicBehaviour {
   public void action() {
    MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.CFP);
    ACLMessage msg = myAgent.receive(mt);
     if (msg != null) {
       // CFP Message received. Process it
       String title = msg.getContent();
       ACLMessage reply = msg.createReply();
 
       Integer price = (Integer) catalogue.get(title);
       if (price != null) {
         // The requested book is available for sale. Reply with the price
         reply.setPerformative(ACLMessage.PROPOSE);
         reply.setContent(String.valueOf(price.intValue()));
       }
       else {
         // The requested book is NOT available for sale.
         reply.setPerformative(ACLMessage.REFUSE);
         reply.setContent("not-available");
       }
       myAgent.send(reply);
     }
    else {
      block();
    }
   }
 }  // End of inner class OfferRequestsServer
 
 /**
    Inner class PurchaseOrdersServer.
    This is the behaviour used by Book-seller agents to serve incoming
    offer acceptances (i.e. purchase orders) from buyer agents.
    The seller agent removes the purchased book from its catalogue
    and replies with an INFORM message to notify the buyer that the
    purchase has been sucesfully completed.
  */
 private class PurchaseOrdersServer extends CyclicBehaviour {
   public void action() {
    MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL);
    ACLMessage msg = myAgent.receive(mt);
     if (msg != null) {
       // ACCEPT_PROPOSAL Message received. Process it
       String title = msg.getContent();
       ACLMessage reply = msg.createReply();
      
       Integer price = (Integer) catalogue.remove(title);
       if (price != null) {
         reply.setPerformative(ACLMessage.INFORM);
         System.out.println(title+" sold to agent "+msg.getSender().getName());
       }
       else {
         // The requested book has been sold to another buyer in the meanwhile .
         reply.setPerformative(ACLMessage.FAILURE);
         reply.setContent("not-available");
       }
       myAgent.send(reply);
     }
    else {
      block();
    }
   }
 }  // End of inner class OfferRequestsServer
}

这个类是买家的界面设计

package sellflag;

import jade.core.AID;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
  @author Giovanni Caire - TILAB
 */
public class FlagBuyerGui extends JFrame {
 private FlagBuyerAgent mybuyerAgent;

 private JTextField titleField;

 FlagBuyerGui(FlagBuyerAgent a) {
  super(a.getLocalName());

  mybuyerAgent = a;

  JPanel p = new JPanel();
  p.setLayout(new GridLayout(1, 1));
  p.add(new JLabel("flag want to buy:"));
  titleField = new JTextField(15);
  p.add(titleField);
  getContentPane().add(p, BorderLayout.CENTER);

  JButton addButton = new JButton("submit");
  addButton.addActionListener( new ActionListener() {
   public void actionPerformed(ActionEvent ev) {
    try {
     String title = titleField.getText().trim();
                   mybuyerAgent.getFlagtitle(title);
                                        titleField.setText("");
    }
    catch (Exception e) {
     JOptionPane.showMessageDialog(FlagBuyerGui.this, "Invalid values. "+e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }
   }
  } );
  p = new JPanel();
  p.add(addButton);
  getContentPane().add(p, BorderLayout.SOUTH);

  // Make the agent terminate when the user closes
  // the GUI using the button on the upper right corner
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    mybuyerAgent.doDelete();
   }
  } );

  setResizable(false);
 }

 public void show() {
  pack();
  Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  int centerX = (int)screenSize.getWidth() / 2;
  int centerY = (int)screenSize.getHeight() / 2;
  setLocation(centerX - getWidth() / 2, centerY - getHeight() / 2);
  super.show();
 }
}
最后一个是卖家界面。。

package sellflag;

import jade.core.AID;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
  @author Giovanni Caire - TILAB
 */
class FlagSellerGui extends JFrame {
 private FlagSellerAgent myAgent;
 
 private JTextField titleField, priceField;
 
 FlagSellerGui(FlagSellerAgent a) {
  super(a.getLocalName());
  
  myAgent = a;
  
  JPanel p = new JPanel();
  p.setLayout(new GridLayout(2, 2));
  p.add(new JLabel("flag title:"));
  titleField = new JTextField(15);
  p.add(titleField);
  p.add(new JLabel("Price:"));
  priceField = new JTextField(15);
  p.add(priceField);
  getContentPane().add(p, BorderLayout.CENTER);
  
  JButton addButton = new JButton("Add");
  addButton.addActionListener( new ActionListener() {
   public void actionPerformed(ActionEvent ev) {
    try {
     String title = titleField.getText().trim();
     String price = priceField.getText().trim();
     myAgent.updateCatalogue(title, Integer.parseInt(price));
     titleField.setText("");
     priceField.setText("");
    }
    catch (Exception e) {
     JOptionPane.showMessageDialog(FlagSellerGui.this, "Invalid values. "+e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }
   }
  } );
  p = new JPanel();
  p.add(addButton);
  getContentPane().add(p, BorderLayout.SOUTH);
  
  // Make the agent terminate when the user closes
  // the GUI using the button on the upper right corner 
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    myAgent.doDelete();
   }
  } );
  
  setResizable(false);
 }
 
 public void show() {
  pack();
  Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  int centerX = (int)screenSize.getWidth() / 2;
  int centerY = (int)screenSize.getHeight() / 2;
  setLocation(centerX - getWidth() / 2, centerY - getHeight() / 2);
  super.show();
 } 
}

都是可运行代码。。。过多的解释不说了,感兴趣的我直接给你我报告。。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值