egat.cli.strategyregret.StrategyRegretCommandHandler.java Source code

Java tutorial

Introduction

Here is the source code for egat.cli.strategyregret.StrategyRegretCommandHandler.java

Source

/*
 * StrategyRegretCommandHandler.java
 *
 * Copyright (C) 2006-2009 Patrick R. Jordan
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
    
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
    
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package egat.cli.strategyregret;

import egat.game.*;
import egat.cli.AbstractGameCommandHandler;
import egat.cli.CommandProcessingException;
import egat.gamexml.ProfileHandler;
import org.apache.commons.cli2.Option;
import org.apache.commons.cli2.CommandLine;
import org.apache.commons.cli2.builder.GroupBuilder;
import org.apache.commons.cli2.builder.DefaultOptionBuilder;
import org.apache.commons.cli2.builder.ArgumentBuilder;
import org.apache.commons.cli2.builder.CommandBuilder;
import org.xml.sax.SAXException;

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.ParserConfigurationException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Set;

/**
 * @author Patrick Jordan
 */
public class StrategyRegretCommandHandler extends AbstractGameCommandHandler {
    private Option playerOption;

    private String playerId;

    private Option profilePathOption;

    private String profilePath;

    private Option uniformOption;

    private boolean uniform;

    @Override
    protected void addAdditionalChildOptions(GroupBuilder groupBuilder) {
        final DefaultOptionBuilder defaultOptionBuilder = new DefaultOptionBuilder();
        final ArgumentBuilder argumentBuilder = new ArgumentBuilder();

        playerOption = defaultOptionBuilder.withLongName("player")
                .withArgument(argumentBuilder.withMinimum(1).withMaximum(1).withName("id").create())
                .withDescription("id of player (non-symmetric) to compute response").create();

        groupBuilder.withOption(playerOption);

        profilePathOption = defaultOptionBuilder.withLongName("profile-path")
                .withArgument(argumentBuilder.withMinimum(1).withMaximum(1).withName("path").create())
                .withDescription("path of profile (strategy with -sym) used as background context").create();

        groupBuilder.withOption(profilePathOption);

        uniformOption = defaultOptionBuilder.withLongName("uniform").withDescription("use a uniform profile")
                .create();

        groupBuilder.withOption(uniformOption);
    }

    @Override
    protected void handleAdditionalChildOptions(CommandLine commandLine) throws CommandProcessingException {
        if (commandLine.hasOption(playerOption)) {
            playerId = (String) commandLine.getValue(playerOption);
        }

        profilePath = (String) commandLine.getValue(profilePathOption);

        uniform = commandLine.hasOption(uniformOption);
    }

    protected String getCommandName() {
        return "strategy-regret";
    }

    protected void processSymmetricGame(MutableSymmetricGame game) throws CommandProcessingException {

        try {
            Profile profile = null;

            if (uniform) {
                Player[] players = game.players().toArray(new Player[0]);
                Strategy[] strategies = new Strategy[players.length];

                Action[] actions = ((Set<Action>) game.getActions()).toArray(new Action[0]);
                Number[] distribution = new Number[actions.length];

                Arrays.fill(distribution, 1.0 / distribution.length);

                Strategy strategy = Games.createStrategy(actions, distribution);
                Arrays.fill(strategies, strategy);

                profile = Games.createProfile(players, strategies);
            } else {
                InputStream inputStream = null;

                inputStream = new FileInputStream(profilePath);

                SAXParserFactory factory = SAXParserFactory.newInstance();

                SAXParser parser = factory.newSAXParser();

                ProfileHandler handler = new ProfileHandler();

                parser.parse(inputStream, handler);

                profile = handler.getProfile();
            }

            findRegret(profile, game);
        } catch (NonexistentPayoffException e) {
            System.err.println(String.format("Could not calculate regret. %s", e.getMessage()));
        } catch (FileNotFoundException e) {
            throw new CommandProcessingException(e);
        } catch (ParserConfigurationException e) {
            throw new CommandProcessingException(e);
        } catch (SAXException e) {
            throw new CommandProcessingException(e);
        } catch (IOException e) {
            throw new CommandProcessingException(e);
        }
    }

    protected void processStrategicGame(MutableStrategicGame game) throws CommandProcessingException {
        try {
            Profile profile = null;

            if (uniform) {
                Player[] players = game.players().toArray(new Player[0]);
                Strategy[] strategies = new Strategy[players.length];

                for (int i = 0; i < players.length; i++) {
                    Action[] actions = ((Set<Action>) game.getActions(players[i])).toArray(new Action[0]);
                    Number[] distribution = new Number[actions.length];
                    Arrays.fill(distribution, 1.0 / distribution.length);
                    strategies[i] = Games.createStrategy(actions, distribution);
                }

                profile = Games.createProfile(players, strategies);

            } else {
                InputStream inputStream = null;

                inputStream = new FileInputStream(profilePath);

                SAXParserFactory factory = SAXParserFactory.newInstance();

                SAXParser parser = factory.newSAXParser();

                ProfileHandler handler = new ProfileHandler();

                parser.parse(inputStream, handler);

                profile = handler.getProfile();
            }

            findRegret(profile, game);
        } catch (NonexistentPayoffException e) {
            System.err.println(String.format("Could not calculate regret. %s", e.getMessage()));
        } catch (FileNotFoundException e) {
            throw new CommandProcessingException(e);
        } catch (ParserConfigurationException e) {
            throw new CommandProcessingException(e);
        } catch (SAXException e) {
            throw new CommandProcessingException(e);
        } catch (IOException e) {
            throw new CommandProcessingException(e);
        }
    }

    protected void findRegret(Profile profile, SymmetricGame game) {
        Player[] players = profile.players().toArray(new Player[0]);
        Strategy[] strategies = new Strategy[players.length];

        for (int i = 0; i < players.length; i++) {
            strategies[i] = profile.getStrategy(players[i]);
        }

        int playerIndex = 0;

        if (playerId != null) {
            for (int i = 0; i < players.length; i++) {
                if (playerId.equals(players[i].getID())) {
                    playerIndex = i;
                    break;
                }
            }
        }

        System.out.print("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        System.out.print("<strategy-regret>");

        double maxPayoff = Double.NEGATIVE_INFINITY;

        Action[] actions = game.getActions().toArray(new Action[0]);
        double[] payoffs = new double[actions.length];

        for (int i = 0; i < actions.length; i++) {
            strategies[playerIndex] = Games.createStrategy(new Action[] { actions[i] }, new Number[] { 1.0 });
            double response = game.payoff(Games.createProfile(players, strategies)).getPayoff(players[0])
                    .getValue();
            payoffs[i] = response;
            maxPayoff = Math.max(response, maxPayoff);
        }

        for (int i = 0; i < actions.length; i++) {
            System.out.print(String.format("<action id=\"%s\" regret=\"%f\" />", actions[i].getID(),
                    maxPayoff - payoffs[i]));
        }

        System.out.print("</strategy-regret>");
    }

    protected void findRegret(Profile profile, StrategicGame game) {
        Player[] players = profile.players().toArray(new Player[0]);
        Strategy[] strategies = new Strategy[players.length];

        for (int i = 0; i < players.length; i++) {
            strategies[i] = profile.getStrategy(players[i]);
        }

        int playerIndex = 0;

        if (playerId != null) {
            for (int i = 0; i < players.length; i++) {
                if (playerId.equals(players[i].getID())) {
                    playerIndex = i;
                    break;
                }
            }
        }

        System.out.print("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        System.out.print(String.format("<strategy-regret player=\"%s\">", players[playerIndex].getID()));

        double maxPayoff = Double.NEGATIVE_INFINITY;

        Action[] actions = game.getActions(players[playerIndex]).toArray(new Action[0]);
        double[] payoffs = new double[actions.length];

        for (int i = 0; i < actions.length; i++) {
            strategies[playerIndex] = Games.createStrategy(new Action[] { actions[i] }, new Number[] { 1.0 });
            double response = game.payoff(Games.createProfile(players, strategies)).getPayoff(players[0])
                    .getValue();
            payoffs[i] = response;
            maxPayoff = Math.max(response, maxPayoff);
        }

        for (int i = 0; i < actions.length; i++) {
            System.out.print(String.format("<action id=\"%s\" regret=\"%f\" />", actions[i].getID(),
                    maxPayoff - payoffs[i]));
        }

        System.out.print("</strategy-regret>");
    }

    @Override
    protected void addCommandDescription(CommandBuilder commandBuilder) {
        commandBuilder.withDescription("regret of each strategy");
    }
}