Агент Java на основе модели


Я работаю на агент-ориентированная модель, как часть моей кандидатской и я ударил контрольно-пропускном пункте. Я начал изучать Java с этим проектом и я наверняка начал бегать раньше, чем ходить. Проблема в том, что я слишком далеко в моей докторской отказаться от этой номинальной. Кроме того, эта работа в значительной степени основан на примере, который поставляется с агентного моделирования программного обеспечения (так называемый Мейсон) и немного суховато. Я хочу начать все заново, но я бегу вне времени и я достиг точки, где я думаю, что мне нужно сделать, это не в моей компетенции.

Я бы с удовольствием некоторые жестокие отзывы и рекомендации. Я действительно пытаюсь возобновить с моделью и доучиться и получить степень. Мне нужна конструктивная критика и обратная связь, чтобы получить меня обратно в паз.

Модель считывает количество ГИС шейп-файлы и отображает дорожную сеть, и два Агентства по окружающей среде карты потока и на заказ открытым исходным кодом индекса уязвимости (OSVI) как простые многоугольники. Модель читает .КШМ и генерирует заданное количество агентов с заданными характеристиками. Агенты размещают на улично-дорожной сети и находятся на точке начала. Каждому агенту присваивается местоположение цели, и случайную скорость. Когда модель запускается, агентам двигаться от A к B, затем они меняют направление и вернуться на свою стартовую позицию. Процесс повторяется, пока пользователь не закроет.

Основной код ниже. Если theres что-нибудь понадобится, дайте мне знать. Все это дело стало совсем запутанным и разносится по нескольким файлам.

MK_7.java

package sim;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
import com.linuxense.javadbf.*;
import java.io.*;

import sim.engine.SimState;
import sim.field.geo.GeomVectorField;
import sim.io.geo.ShapeFileImporter;
import sim.util.Bag;
import sim.util.geo.GeomPlanarGraph;
import sim.util.geo.GeomPlanarGraphEdge;
import sim.util.geo.MasonGeometry;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.planargraph.Node;

import ec.util.MersenneTwisterFast;

public class MK_7 extends SimState  {

    //////////////////////////////////////////////////////////////////////////////
    ///////////////////////////// MODEL PARAMETERS ///////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    private static final long serialVersionUID = -4554882816749973618L;

    ///////////////////////////// Containers /////////////////////////////////////
    public GeomVectorField roads = new GeomVectorField();
    public GeomVectorField world = new GeomVectorField();
    public GeomVectorField flood3 = new GeomVectorField();
    public GeomVectorField flood2 = new GeomVectorField();
    //public GeomVectorField HouseholdsFZ = new GeomVectorField();
    //public GeomVectorField Households = new GeomVectorField();
    public GeomVectorField agents = new GeomVectorField();
    //public GeomVectorField ngoagents = new GeomVectorField();

    ///////////////////////////// Network ////////////////////////////////////////
    public GeomPlanarGraph network = new GeomPlanarGraph();
    // Stores road network connections
    public GeomVectorField junctions = new GeomVectorField();
    // Stores nodes for road intersections
    HashMap<Integer, GeomPlanarGraphEdge> idsToEdges =
        new HashMap<Integer, GeomPlanarGraphEdge>();
    public HashMap<GeomPlanarGraphEdge, ArrayList<agents.MainAgent>> edgeTraffic =
        new HashMap<GeomPlanarGraphEdge, ArrayList<agents.MainAgent>>();
    public GeomVectorField mainagents = new GeomVectorField();

    // Model ArrayLists for agents and OSVI Polygons
    ArrayList<agents.MainAgent> agentList = new ArrayList<agents.MainAgent>();
    ArrayList<Polygon> polys = new ArrayList<Polygon>();
    ArrayList<String> csvData = new ArrayList<String>();

    // Here we force the agents to go to or from work at any time
    public boolean goToWork = true;
    public boolean getGoToWork()    {
        return goToWork;
    }

    //////////////////////////////////////////////////////////////////////////////
    /////////////////////////// BEGIN FUNCTIONS //////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    /**
     * //////////////////////// Model Constructor ////////////////////////////////
     * Model Constructor
     */
    public MK_7(long seed)  {
        super(seed);
        random = new MersenneTwisterFast(12345);
    }

    /**
     * //////////////////////// OSVI Polygon Setup ///////////////////////////////
     * Polygon Setup
     */
    void setup()
    {
        // copy over the geometries into a list of Polygons
        Bag ps = world.getGeometries();
        polys.addAll(ps);
        }

    /**
     * //////////////////////// Model Initialisation /////////////////////////////
     * Model Initialisation
     */
    @Override
    public void start() {
        super.start();
        System.out.println("Reading shapefiles...");

        //////////////////////////////////////////////////////////////////////////
        /////////////////////////// READ IN DATA /////////////////////////////////
        //////////////////////////////////////////////////////////////////////////

        /*
        src/
            data/
                .shp, .dbf, .csv ...
        sim/
            MK_7/
                .java files
         */

        try {
            // read in the roads shapefile to create the transit network
            URL roadsFile = MK_7.class.getResource
                    ("/data/Final_ITN.shp");
            ShapeFileImporter.read(roadsFile, roads);
            System.out.println("    Roads shapefile: " +roadsFile);

            Envelope MBR = roads.getMBR();

            // read in the LSOA shapefile to create the backgrounds
            // URL areasFile = MK_4.class.getResource
            //      ("/data/Final_LSOA.shp");
            //   Bag desiredAttributes = new Bag();
            //   desiredAttributes.add("RC_RankCol");
            //
            //   try {
            //      ShapeFileImporter.read(areasFile, world, desiredAttributes);
            //   }
            //   catch (FileNotFoundException ex){
            //      }

            URL wardsFile = MK_7.class.getResource
                    ("/data/Final_LSOA.shp");
            ShapeFileImporter.read(wardsFile, world, Polygon.class);
            System.out.println("    LSOA shapefile: " +wardsFile);

            MBR.expandToInclude(world.getMBR());

            // read in the FZ3 file
            URL flood3File = MK_7.class.getResource
                    ("/data/NorfolkFZ3.shp");
            ShapeFileImporter.read(flood3File, flood3);
            System.out.println("    FZ3 shapefile: " +flood3File);

            MBR.expandToInclude(flood3.getMBR());

            // read in the FZ2 file
            URL flood2File = MK_7.class.getResource
                    ("/data/NorfolkFZ2.shp");
            ShapeFileImporter.read(flood2File, flood2);
            System.out.println("    FZ2 shapefile: " +flood2File);

            MBR.expandToInclude(flood2.getMBR());

            /*
            // read in the household files
            URL HouseholdsFZFile = MK_2.class.getResource
                    ("/data/Buildings_IN_FZ_Snapped_to_ITN.shp");
            ShapeFileImporter.read(HouseholdsFZFile, HouseholdsFZ);
            System.out.println("Households in FZ shapefile: " +HouseholdsFZFile);

            MBR.expandToInclude(HouseholdsFZ.getMBR());

            // read in the FZ2 file
            URL HouseholdsFile = MK_2.class.getResource
                    ("/data/Buildings_NOT_in_FZ_Snapped_to_ITN.shp");
            ShapeFileImporter.read(HouseholdsFile, Households);
            System.out.println("Households not in FZ shapefile: " +HouseholdsFile);
            System.out.println();

            MBR.expandToInclude(Households.getMBR());
            */

            createNetwork();
            setup();

            //////////////////////////////////////////////////////////////////////
            /////////////////////////// CLEANUP //////////////////////////////////
            //////////////////////////////////////////////////////////////////////

            // clear any existing agents from previous runs
            agents.clear();
            //ngoagents.clear();

            //////////////////////////////////////////////////////////////////////
            /////////////////////////// AGENTS ///////////////////////////////////
            //////////////////////////////////////////////////////////////////////

            // initialize agents using the following source .CSV files
            agentGoals("/data/AgentGoals.csv");
            populateAgent("/data/NorfolkITNAGENT.csv");

            System.out.println();
            System.out.println("Starting simulation...");

            // standardize the MBRs so that the visualization lines up
            // and everyone knows what the standard MBR is
            roads.setMBR(MBR);
            world.setMBR(MBR);
            flood3.setMBR(MBR);
            flood2.setMBR(MBR);
            //HouseholdsFZ.setMBR(MBR);
            //Households.setMBR(MBR);
            agents.setMBR(MBR);
            //ngoagents.setMBR(MBR);

            // Ensure that the spatial index is updated after all the agents move
            schedule.scheduleRepeating( agents.scheduleSpatialIndexUpdater(),
                    Integer.MAX_VALUE, 1.0);
            //schedule.scheduleRepeating( ngoagents.scheduleSpatialIndexUpdater(),
            //      Integer.MAX_VALUE, 1.0);


            /** Steppable that flips Agent paths once everyone reaches
             * their destinations

            Steppable flipper = new Steppable() {
                @Override
                public void step(SimState state)
                {

                    MK_7 gstate = (MK_7) state;

                    // pass to check if anyone has not yet reached work
                    //for (MainAgent a : gstate.agentList)
                    //{
                        ///if (!a.reachedDestination)
                        //{
                        //    return; // someone is still moving: let him do so
                      //  }
                    //}
                    // send everyone back in the opposite direction now
                    //boolean toWork = gstate.goToWork;
                   // gstate.goToWork = !toWork;

                    // otherwise everyone has reached their latest destination:
                    // turn them back
                    for (MainAgent a : gstate.agentList)
                        if (a.reachedDestination) {
                            a.flipPath();
                        }
                }
            };
            schedule.scheduleRepeating(flipper, 10);
             */

        } catch (FileNotFoundException e)
        {
            System.out.println("Error: missing required data file");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * //////////////////////// Model Finish & Cleanup ///////////////////////////
     * Finish the simulation and clean up
     */
    public void finish()    {
        super.finish();
        System.out.println();
        System.out.println("Simulation ended by user.");
        /*
        System.out.println("Attempting to export agent data...");
        try {
            ShapeFileExporter.write("agents", agents);
        } catch (Exception e)   {
            System.out.println("Export failed.");
            e.printStackTrace();
        }
        */
    }

    /**
     * //////////////////////// Create Road Network //////////////////////////////
     * Create the road network the agents will traverse
     */
    private void createNetwork()    {
        System.out.println("Creating road network..." +roads);
        System.out.println();
        network.createFromGeomField(roads);

        for (Object o : network.getEdges()) {
            GeomPlanarGraphEdge e = (GeomPlanarGraphEdge) o;

            idsToEdges.put(e.getIntegerAttribute("ROAD_ID").intValue(), e);

            e.setData(new ArrayList<agents.MainAgent>());
        }

        addIntersectionNodes(network.nodeIterator(), junctions);
    }


    /**
    * ///////////////////////// Setup agentGoals /////////////////////////////////
    * Read in the agent goals CSV
    * @param agentfilename
    * @return
    *
    */
    public ArrayList<String> agentGoals(String agentfilename) throws IOException{
        String csvGoal = null;
        BufferedReader agentGoalsBuffer = null;

        String agentFilePath = MK_7.class.getResource(agentfilename).getPath();
        FileInputStream agentfstream = new FileInputStream(agentFilePath);
        System.out.println("Reading Agent's Goals CSV file: " +agentFilePath);

        try {
            agentGoalsBuffer = new BufferedReader
                    (new InputStreamReader(agentfstream));
            agentGoalsBuffer.readLine();
            while ((csvGoal = agentGoalsBuffer.readLine()) != null) {
                String[] splitted = csvGoal.split(",");

                ArrayList<String> agentGoalsResult = 
                        new ArrayList<String>(splitted.length);
                for (String data : splitted)
                    agentGoalsResult.add(data);
                csvData.addAll(agentGoalsResult);
            }
            System.out.println("Full csvData Array: " +csvData);

        } finally {
            if (agentGoalsBuffer != null)
                agentGoalsBuffer.close();
        }
        return csvData;
    }

    /**
     * //////////////////////// Setup mainAgent //////////////////////////////////
     * Read in the population files and create appropriate populations
     * @param filename
     */
    public void populateAgent(String filename)  {
        try {
            String filePath = MK_7.class.getResource(filename).getPath();
            FileInputStream fstream = new FileInputStream(filePath);
            System.out.println();
            System.out.println("Populating model with Agents: " +filePath);

            BufferedReader d = new BufferedReader(new InputStreamReader(fstream));
            String s;

            // get rid of the header
            d.readLine();
            // read in all data
            while ((s = d.readLine()) != null)  {
                String[] bits = s.split(",");

                int pop = Integer.parseInt(bits[2]);

                //moveRate = (int)(Math.random()*70) + 1;
                //System. out.println("MoveRate = " + moveRate );
                //int mainAgentSpeed = MainAgent.MoveRate;
                //System.out.println("Main Agent speed = " +mainAgentSpeed);

                String homeTract = bits[3];
                String ROAD_ID = bits[3];

                Random randomiser = new Random();
                String random = csvData.get(new Random().nextInt(csvData.size()));
                String goalTract = random;
                System.out.println();
                System.out.println("Agent goalTract: " +goalTract);

                GeomPlanarGraphEdge startingEdge = idsToEdges.get(
                        (int) Double.parseDouble(ROAD_ID));
                GeomPlanarGraphEdge goalEdge = idsToEdges.get(
                        (int) Double.parseDouble(goalTract));
                        //reads the .CSV column
                        //goals[ random.nextInt(goals.length)]);
                        // uses the hardcoded 'goals' from above

                for (int i = 0; i < pop; i++)   {
                    //pop; i++) {   // NO IDEA IF THIS MAKES A DIFFERENCE!?!
                    agents.MainAgent a = new agents.MainAgent
                            (this, homeTract, startingEdge, goalEdge);

                    boolean successfulStart = a.start(this);
                    //System.out.println("Starting...");

                    if (!successfulStart)   {
                        System.out.println("Main agents added successfully!!");
                        continue; // DON'T ADD IT if it's bad
                    }

                    //MasonGeometry newGeometry = new MasonGeometry(a.getGeometry());
                    MasonGeometry newGeometry = a.getGeometry();
                    newGeometry.isMovable = true;
                    agents.addGeometry(newGeometry);
                    agentList.add(a);
                    schedule.scheduleRepeating(a);
                }
            }

            d.close();

        } catch (Exception e) {
                System.out.println("ERROR: issue with population file: ");
                e.printStackTrace();
        }
    }

    /**
     * //////////////////////// Network Intersections ////////////////////////////
     * adds nodes corresponding to road intersections to GeomVectorField
     *
     * @param nodeIterator Points to first node
     * @param intersections GeomVectorField containing intersection geometry
     *
     * Nodes will belong to a planar graph populated from LineString network.
     */
    private void addIntersectionNodes(Iterator<?> nodeIterator,
                                      GeomVectorField intersections)    {
        GeometryFactory fact = new GeometryFactory();
        Coordinate coord = null;
        Point point = null;
        @SuppressWarnings("unused")
        int counter = 0;

        while (nodeIterator.hasNext())  {
            Node node = (Node) nodeIterator.next();
            coord = node.getCoordinate();
            point = fact.createPoint(coord);

            junctions.addGeometry(new MasonGeometry(point));
            counter++;
        }
    }

    /**
     * //////////////////////// Main Function ////////////////////////////////////
     * Main function allows simulation to be run in stand-alone, non-GUI mode
     */
    public static void main(String[] args)  {
        doLoop(MK_7.class, args);
        System.exit(0);
    }
}

MK_7WithUI.java

package sim;

import java.awt.Color;
import java.awt.Graphics2D;

import javax.swing.JFrame;

import org.jfree.data.xy.XYSeries;

import sim.display.Console;
import sim.display.Controller;
import sim.display.Display2D;
import sim.display.GUIState;
import sim.engine.SimState;
import sim.engine.Steppable;
import sim.portrayal.DrawInfo2D;
import sim.portrayal.geo.GeomPortrayal;
import sim.portrayal.geo.GeomVectorFieldPortrayal;
import sim.util.media.chart.TimeSeriesChartGenerator;
import agents.MainAgent;

public class MK_7WithUI extends GUIState    {

    //////////////////////////////////////////////////////////////////////////////
    /////////////////////////// DISPLAY FUNCTIONS ////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    private Display2D display;
    private JFrame displayFrame;

    //private GeomVectorFieldPortrayal lsoaPortrayal = new GeomVectorFieldPortrayal();
    GeomVectorFieldPortrayal polyPortrayal = new GeomVectorFieldPortrayal(true);
    private GeomVectorFieldPortrayal roadsPortrayal = new GeomVectorFieldPortrayal(true);
    private GeomVectorFieldPortrayal flood3Portrayal = new GeomVectorFieldPortrayal();
    private GeomVectorFieldPortrayal flood2Portrayal = new GeomVectorFieldPortrayal();
    private GeomVectorFieldPortrayal agentPortrayal = new GeomVectorFieldPortrayal();
    //SparseGridPortrayal2D agentPortrayal = new SparseGridPortrayal2D();
    TimeSeriesChartGenerator trafficChart;
    XYSeries maxSpeed;
    XYSeries avgSpeed;
    XYSeries minSpeed;

    //////////////////////////////////////////////////////////////////////////////
    /////////////////////////// BEGIN FUNCTIONS //////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    /**
     * ///////////////////////// Default constructor /////////////////////////////
     * Default constructor
     */
    protected MK_7WithUI(SimState state)    {
            super(state);
        }

    /**
     * //////////////////////// Portrayal Setup //////////////////////////////////
     * Sets up the portrayals and charts for the simulation
     */
    private void setupPortrayals()  {
        sim.MK_7 world = (sim.MK_7) state;

        // the polygon portrayal
        polyPortrayal.setField(world.world);
        polyPortrayal.setPortrayalForAll(new PolyPortrayal());

        display.reset();

        display.repaint();
    }

        /**
         * ///////////////////////// Main Function ///////////////////////////////
         *
         * Main function to run the simulation
         * @param args
         */
        public static void main(String[] args)  {
            MK_7WithUI simple = new MK_7WithUI(
                    new sim.MK_7(System.currentTimeMillis()));
            Console c = new Console(simple);
            c.setVisible(true);
        }

        /**
         * //////////////////////// Simulation Name //////////////////////////////
         * @return name of the simulation
         */
        public static String getName()  {
            return "EngD ABM Model MK_7";
        }

        /**
         *  /////////////////////// Model Modification ///////////////////////////
         *  This must be included to have model tab, which allows mid-simulation
         *  modification of the coefficients
         */
        public Object getSimulationInspectedObject()    {
            return state;
        }  // non-volatile

        /**
         * //////////////////////// Model Setup //////////////////////////////////
         * Called when starting a new run of the simulation. Sets up the portrayals
         * and chart data.
         */
        public void start() {
            super.start();

            setupPortrayals();

            sim.MK_7 world = (sim.MK_7) state;

            maxSpeed = new XYSeries("Max Speed");
            avgSpeed = new XYSeries("Average Speed");
            minSpeed = new XYSeries("Min Speed");
            trafficChart.removeAllSeries();
            trafficChart.addSeries(maxSpeed, null);
            trafficChart.addSeries(avgSpeed, null);
            trafficChart.addSeries(minSpeed, null);

            state.schedule.scheduleRepeating(new Steppable()    {
                private static final long serialVersionUID = -3749005402522867098L;

                public void step(SimState state)    {
                    sim.MK_7 world = (sim.MK_7) state;
                    double maxS = 0, minS = 10000, avgS = 0, count = 0;
                    //////////////////////////// Main Agent //////////////////////
                    for (MainAgent a : world.agentList) {
                        if (a.reachedGoal)  {
                            continue;
                        }
                        count++;
                        double speed = Math.abs(a.speed);
                        avgS += speed;
                        if (speed > maxS)   {
                            maxS = speed;
                        }
                        if (speed < minS)   {
                            minS = speed;
                        }
                    }

                    double time = state.schedule.time();
                    avgS /= count;
                    maxSpeed.add(time, maxS, true);
                    minSpeed.add(time, minS, true);
                    avgSpeed.add(time, avgS, true);
                }
            });

            /**
             * Sets up the portrayals within the map visualization.
             */

            roadsPortrayal.setField(world.roads);
            roadsPortrayal.setPortrayalForAll(new GeomPortrayal
                    (Color.DARK_GRAY, 0.0005, false));
            polyPortrayal.setField(world.world);
            polyPortrayal.setPortrayalForAll(new PolyPortrayal());
            flood3Portrayal.setField(world.flood3);
            flood3Portrayal.setPortrayalForAll(new GeomPortrayal
                    (Color.CYAN, true));
            flood2Portrayal.setField(world.flood2);
            flood2Portrayal.setPortrayalForAll(new GeomPortrayal
                    (Color.BLUE, true));
            agentPortrayal.setField(world.agents);
            agentPortrayal.setPortrayalForAll(new GeomPortrayal
                    (Color.MAGENTA, 150, true));
            //agentPortrayal.setPortrayalForAll(new GeomPortrayal());

            display.reset();
            display.setBackdrop(Color.WHITE);
            display.repaint();

        }

        /**
         * /////////////////////// Poly Portrayal Colours ////////////////////////
         * The portrayal used to display Polygons with the appropriate color
         * */
        class PolyPortrayal extends GeomPortrayal
        {

            private static final long serialVersionUID = 1L;

            @Override
            public void draw(Object object, Graphics2D graphics, DrawInfo2D info)
            {
                Polygon poly = (Polygon) object;

                if (poly.getSoc().equals("red"))
                {
                    paint = Color.red;
                }

                else if (poly.getSoc().equals("orange"))
                {
                    paint = Color.orange;
                }

                else if (poly.getSoc().equals("yellow"))
                {
                    paint = Color.yellow;
                }

                else if (poly.getSoc().equals("green"))
                {
                    paint = Color.green;
                }
                else
                {
                    paint = Color.gray;
                }

                super.draw(object, graphics, info);
            }

        }

        /**
         * /////////////////////// Visualisation Format //////////////////////////
         * Initializes the simulation visualization. Sets up the display
         * window, the JFrames, and the chart structure.
         */
        public void init(Controller c)
        {
            super.init(c);

            /////////////////////////// MAIN DISPLAY /////////////////////////////
            // makes the displayer and visualises the maps
            display = new Display2D(1200, 600, this);
            // turn off clipping
            // display.setClipping(false);

            displayFrame = display.createFrame();
            displayFrame.setTitle("EngD ABM Model MK_7");
            c.registerFrame(displayFrame); // register the frame so it appears in

            // Put portrayals in order from bottom layer to top
            displayFrame.setVisible(true);
            display.attach(polyPortrayal, "LSOA");
            display.attach(flood2Portrayal, "FZ2 Zone");
            display.attach(flood3Portrayal, "FZ3 Zone");
            display.attach(roadsPortrayal, "Roads");
            display.attach(agentPortrayal, "Agents");

            ///////////////////////////// CHART //////////////////////////////////
            trafficChart = new TimeSeriesChartGenerator();
            trafficChart.setTitle("Traffic Stats");
            trafficChart.setYAxisLabel("Speed");
            trafficChart.setXAxisLabel("Time");
            JFrame chartFrame = trafficChart.createFrame(this);
            chartFrame.pack();
            c.registerFrame(chartFrame);

        }

        /**
         * /////////////////////// Model Finish //////////////////////////////////
         * Quits the simulation and cleans up.
         */
        public void quit()  {
            System.out.println("Model closed.");
            super.quit();

            if (displayFrame != null)   {
                displayFrame.dispose();
            }
            displayFrame = null; // let gc
            display = null; // let gc
        }
    }

MainAgent.java

package agents;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;

import network.AStar;
import sim.MK_7;
import sim.engine.SimState;
import sim.engine.Steppable;
import sim.portrayal.DrawInfo2D;
import sim.util.geo.GeomPlanarGraphDirectedEdge;
import sim.util.geo.GeomPlanarGraphEdge;
import sim.util.geo.MasonGeometry;
import sim.util.geo.PointMoveTo;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.linearref.LengthIndexedLine;
import com.vividsolutions.jts.planargraph.Node;

public final class MainAgent implements Steppable   {
    private static final long serialVersionUID = -1113018274619047013L;

    //////////////////////////////////////////////////////////////////////////////
    /////////////////////////////// PARAMETERS ///////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    MK_7 world;
    // Residence/Work Attributes

    String homeTract = "";
    String goalTract = "";
    Node homeNode = null;
    Node workNode = null;
    // point that denotes agent's position
    // private Point location;
    private MasonGeometry location; // point that denotes agent's position
    // How much to move the agent by in each step()
    private double basemoveRate = 10.0;
    private double moveRate = basemoveRate;
    //private double moveRate = 70;
    private LengthIndexedLine segment = null;
    double startIndex = 0.0; // start position of current line
    double endIndex = 0.0; // end position of current line
    double currentIndex = 0.0; // current location along line
    GeomPlanarGraphEdge currentEdge = null;
    private Color headingToHQ = Color.black;
    private Color headingToGoal = Color.red;
    int linkDirection = 1;
    public double speed = 0; // useful for graph
    ArrayList<GeomPlanarGraphDirectedEdge> pathFromHomeToWork =
        new ArrayList<GeomPlanarGraphDirectedEdge>();
    int indexOnPath = 0;
    int pathDirection = 1;
    public boolean reachedGoal = false;
    PointMoveTo pointMoveTo = new PointMoveTo();

    static private GeometryFactory fact = new GeometryFactory();

    /**
     * //////////////////////// Model Constructor ////////////////////////////////
     * Constructor: specifies parameters for Agents
     * Default Wrapper Constructor: provides the default parameters
     *
     * //@param location - Coordinate indicating the initial position of the Agent
     * //@param homeNode - Coordinate indicating the Agent's home location
     * //@param workNode - Coordinate indicating the Agent's workplace
     * //@param world - reference to the containing NorfolkRouting instance
     */
    public MainAgent(MK_7 g, String homeTract, GeomPlanarGraphEdge startingEdge,
            GeomPlanarGraphEdge goalEdge)   {
       world = g;

       // set up information about where the node is and where it's going
       homeNode = startingEdge.getDirEdge(0).getFromNode();
       workNode = goalEdge.getDirEdge(0).getToNode();
       this.homeTract = homeTract;
       this.goalTract = goalTract;

       // set the location to be displayed
       //GeometryFactory fact = new GeometryFactory();

       location = new MasonGeometry(fact.createPoint(new Coordinate(10, 10))) ;

       location.isMovable = true;

       // Now set up attributes for this agent
       if (g.random.nextBoolean())  {
           location.addStringAttribute("TYPE", "4x4");
           int age = (int) (20.0 + 2.0 * g.random.nextGaussian());
           location.addIntegerAttribute("AGE", age);
       }
       else {
           location.addStringAttribute("TYPE", "Car");
           int age = (int) (40.0 + 9.0 * g.random.nextGaussian());
           location.addIntegerAttribute("AGE", age);
       }

       // Not everyone moves at the same speed
       // Assigns random speed
       //moveRate *= Math.abs(g.random.nextGaussian());
       // Assigns random speed between 0-70
       moveRate = (int)(Math.random()*70) + 1;
       System. out.println("Agent's MoveRate = " + moveRate );
       location.addDoubleAttribute("MOVE RATE", moveRate);

       Coordinate startCoord = null;
       startCoord = homeNode.getCoordinate();
       updatePosition(startCoord);
    }

    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////// AGENT ATTRIBUTES ////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    /**
     * ////////////////////////// Agent Type /////////////////////////////////////
     * @return string indicating whether Agent is a "4x4" or a "Car"
     */
    public String getType() {
        return location.getStringAttribute("TYPE");
    }

    /**
    * ////////////////////////// Agent Colour ////////////////////////////////////
    * Want to change the colour of the Agent's depending on their status:
    * "heading back to HQ" or "heading to goal"
    *
    */

    public final void draw(Object object, Graphics2D graphics, DrawInfo2D info) {
       if( reachedGoal )
           graphics.setColor( headingToGoal );
       else
           graphics.setColor( headingToHQ );

       // this code was stolen from OvalPortrayal2D
       int x = (int)(info.draw.x - info.draw.width / 20.0);
       int y = (int)(info.draw.y - info.draw.height / 20.0);
       int width = (int)(info.draw.width);
       int height = (int)(info.draw.height);
       graphics.fillOval(x,y,width, height);
    }

    //////////////////////////////////////////////////////////////////////////////
    //////////////////////////////// ROUTING /////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////

    /**
    * ////////////////////////// A* Route Initialisation /////////////////////////
    * Initialization of an Agent: find an A* path to work!
    *
    * @param state
    * @return whether or not the agent successfully found a path to work
    */
   public boolean start(MK_7 state) {
       findNewAStarPath(state);
       if (pathFromHomeToWork.isEmpty())    {
           System.out.println("Initialization of a Agent (" +homeTract
                + ") failed: it is located in a part of the network that cannot "
                + "access the given goal.");
           return false;
       } else   {
           return true;
       }
   }

   /**
    * ////////////////////////// Plot A* Route ///////////////////////////////////
    * Plots a path between the Agent's home Node and its work Node
    */
   private void findNewAStarPath(MK_7 geoTest)  {

       // get the home and work Nodes with which this Agent is associated
       Node currentJunction = geoTest.network.findNode
               (location.geometry.getCoordinate());
       Node destinationJunction = workNode;

       if (currentJunction == null) {
           return; // just a check
       }
       // find the appropriate A* path between them
       AStar pathfinder = new AStar();
       ArrayList<GeomPlanarGraphDirectedEdge> path =
           pathfinder.astarPath(currentJunction, destinationJunction);

       // if the path works, lay it in
       if (path != null && path.size() > 0) {

           // save it
           pathFromHomeToWork = path;

           // set up how to traverse this first link
           GeomPlanarGraphEdge edge =
               (GeomPlanarGraphEdge) path.get(0).getEdge();
           setupEdge(edge);

           // update the current position for this link
           updatePosition(segment.extractPoint(currentIndex));

       }
   }

   double progress(double val)  {
       double edgeLength = currentEdge.getLine().getLength();
       double traffic = world.edgeTraffic.get(currentEdge).size();
       double factor = 1000 * edgeLength / (traffic * 5);
       factor = Math.min(1, factor);
       return val * linkDirection * factor;
   }

   /**
    * ////////////////////////// Step to Move Agent //////////////////////////////
    * Called every tick by the scheduler.
    * Moves the agent along the path.
    */
   public void step(SimState state) {
       // check that we've been placed on an Edge
       if (segment == null) {
           return;
       } // check that we haven't already reached our destination
       else if (reachedGoal)    {
           System.out.println(this + " has reached its HOME");
           flipPath();
       }

       // make sure that we're heading in the right direction
       //boolean toWork = ((MK_7) state).goToWork;
       // if ((toWork && pathDirection < 0) || (!toWork && pathDirection > 0))  {
       //     flipPath();
       // }

       // move along the current segment
       speed = progress(moveRate);
       currentIndex += speed;

       // check to see if the progress has taken the current index beyond its goal
       // given the direction of movement. If so, proceed to the next edge
       if (linkDirection == 1 && currentIndex > endIndex)   {
           Coordinate currentPos = segment.extractPoint(endIndex);
           updatePosition(currentPos);
           transitionToNextEdge(currentIndex - endIndex);
       } else if (linkDirection == -1 && currentIndex < startIndex) {
           Coordinate currentPos = segment.extractPoint(startIndex);
           updatePosition(currentPos);
           transitionToNextEdge(startIndex - currentIndex);
       } else
       { // just update the position!
           Coordinate currentPos = segment.extractPoint(currentIndex);

           updatePosition(currentPos);
       }
   }

   /**
    * ////////////////////////// Flip Agent's Route //////////////////////////////
    * Flip the agent's path around
    */
   public void flipPath()   {
       reachedGoal = false;
       pathDirection = -pathDirection;
       linkDirection = -linkDirection;
   }

   /**
    * ////////////////////////// Move Agent to Next Edge /////////////////////////
    * Transition to the next edge in the path
    * @param residualMove the amount of distance the agent can still travel
    * this turn
    */
   void transitionToNextEdge(double residualMove)   {

       // update the counter for where the index on the path is
       indexOnPath += pathDirection;

       // check to make sure the Agent has not reached the end
       // of the path already
       if ((pathDirection > 0 && indexOnPath >= pathFromHomeToWork.size())
               || (pathDirection < 0 && indexOnPath < 0))
                // depends on where you're going!
       {
           System.out.println(this + " has reached its DESTINATION");
           reachedGoal = true;
           indexOnPath -= pathDirection; // make sure index is correct
           return;
       }

       // move to the next edge in the path
       GeomPlanarGraphEdge edge = (GeomPlanarGraphEdge)
               pathFromHomeToWork.get(indexOnPath).getEdge();
       setupEdge(edge);
       speed = progress(residualMove);
       currentIndex += speed;

       // check to see if the progress has taken the current index beyond its goal
       // given the direction of movement. If so, proceed to the next edge
       if (linkDirection == 1 && currentIndex > endIndex)   {
           transitionToNextEdge(currentIndex - endIndex);
       } else if (linkDirection == -1 && currentIndex < startIndex) {
           transitionToNextEdge(startIndex - currentIndex);
       }
   }

   /**
    * ////////////////////////// Agent's Route Info //////////////////////////////
    * Sets the Agent up to proceed along an Edge
    * @param edge the GeomPlanarGraphEdge to traverse next
    */
   void setupEdge(GeomPlanarGraphEdge edge) {

       // clean up on old edge
       if (currentEdge != null) {
           ArrayList<MainAgent> traffic = world.edgeTraffic.get(currentEdge);
           traffic.remove(this);
       }
       currentEdge = edge;

       // update new edge traffic
       if (world.edgeTraffic.get(currentEdge) == null)  {
           world.edgeTraffic.put(currentEdge, new ArrayList<MainAgent>());
       }
       world.edgeTraffic.get(currentEdge).add(this);

       // set up the new segment and index info
       LineString line = edge.getLine();
       segment = new LengthIndexedLine(line);
       startIndex = segment.getStartIndex();
       endIndex = segment.getEndIndex();
       linkDirection = 1;

       // check to ensure that Agent is moving in the right direction
       double distanceToStart = line.getStartPoint().distance(location.geometry),
           distanceToEnd = line.getEndPoint().distance(location.geometry);
       if (distanceToStart <= distanceToEnd)    { // closer to start
           currentIndex = startIndex;
           linkDirection = 1;
       } else if (distanceToEnd < distanceToStart)  { // closer to end
           currentIndex = endIndex;
           linkDirection = -1;
       }
   }

   /**
    * ////////////////////////// Move Agent //////////////////////////////////////
    * Move the agent to the given coordinates
    */
   public void updatePosition(Coordinate c) {
       pointMoveTo.setCoordinate(c);
       // location.geometry.apply(pointMoveTo);

       world.agents.setGeometryLocation(location, pointMoveTo);
   }

   /**
    * ////////////////////////// Agent's Location ////////////////////////////////
    * Return geometry representing agent location
    */
   public MasonGeometry getGeometry()   {
       return location;
   }
}

AStar.java

package network;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.planargraph.DirectedEdgeStar;
import com.vividsolutions.jts.planargraph.Node;
import sim.util.geo.GeomPlanarGraphDirectedEdge;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * AStar.java
 *
 * Copyright 2011 by Sarah Wise, Mark Coletti, Andrew Crooks, and
 * George Mason University.
 *
 * Licensed under the Academic Free License version 3.0
 *
 * See the file "LICENSE" for more information
 *
 * $Id: AStar.java 842 2012-12-18 01:09:18Z mcoletti $
 */
public class AStar {

    //////////////////////////////////////////////////////////////////////////////
    /////////////////////////////// PARAMETERS ///////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////
    public ArrayList<GeomPlanarGraphDirectedEdge> astarPath(Node start, Node goal)  {
        // initial check
        if (start == null || goal == null)  {
            System.out.println("Error: invalid node provided to AStar");
        }

        // set up the containers for the result
        ArrayList<GeomPlanarGraphDirectedEdge> result =
            new ArrayList<GeomPlanarGraphDirectedEdge>();

        // containers for the metainformation about the Nodes relative to the
        // A* search
        HashMap<Node, AStarNodeWrapper> foundNodes =
            new HashMap<Node, AStarNodeWrapper>();

        AStarNodeWrapper startNode = new AStarNodeWrapper(start);
        AStarNodeWrapper goalNode = new AStarNodeWrapper(goal);
        foundNodes.put(start, startNode);
        foundNodes.put(goal, goalNode);

        startNode.gx = 0;
        startNode.hx = heuristic(start, goal);
        startNode.fx = heuristic(start, goal);

        // A* containers: nodes to be investigated, nodes that have been investigated
        ArrayList<AStarNodeWrapper> closedSet = new ArrayList<AStarNodeWrapper>(),
            openSet = new ArrayList<AStarNodeWrapper>();
        openSet.add(startNode);


        while (openSet.size() > 0)  {
            // while there are reachable nodes to investigate
            AStarNodeWrapper x = findMin(openSet);
            // find the shortest path so far
            if (x.node == goal) {
                // we have found the shortest possible path to the goal!
                // Reconstruct the path and send it back.
                return reconstructPath(goalNode);
            }
            openSet.remove(x);
            // maintain the lists
            closedSet.add(x);

            // check all the edges out from this Node
            DirectedEdgeStar des = x.node.getOutEdges();
            for (Object o : des.getEdges().toArray())   {
                GeomPlanarGraphDirectedEdge l = (GeomPlanarGraphDirectedEdge) o;
                Node next = null;
                next = l.getToNode();

                // get the A* meta information about this Node
                AStarNodeWrapper nextNode;
                if (foundNodes.containsKey(next))   {
                    nextNode = foundNodes.get(next);
                } else  {
                    nextNode = new AStarNodeWrapper(next);
                    foundNodes.put(next, nextNode);
                }

                if (closedSet.contains(nextNode))   {
                    // it has already been considered   
                    continue;
                }

                // otherwise evaluate the cost of this node/edge combo
                double tentativeCost = x.gx + length(l);
                boolean better = false;

                if (!openSet.contains(nextNode))    {
                    openSet.add(nextNode);
                    nextNode.hx = heuristic(next, goal);
                    better = true;
                } else if (tentativeCost < nextNode.gx) {
                    better = true;
                }

                // store A* information about this promising candidate node
                if (better) {
                    nextNode.cameFrom = x;
                    nextNode.edgeFrom = l;
                    nextNode.gx = tentativeCost;
                    nextNode.fx = nextNode.gx + nextNode.hx;
                }
            }
        }
        return result;
    }

    /**
     * ///////////////////////////// Path Array //////////////////////////////////
     * Takes the information about the given node n and returns the path that
     * found it.
     * @param n the end point of the path
     * @return an ArrayList of GeomPlanarGraphDirectedEdges that lead from the
     * given Node to the Node from which the serach began
     */
    ArrayList<GeomPlanarGraphDirectedEdge> reconstructPath(AStarNodeWrapper n)  {
        ArrayList<GeomPlanarGraphDirectedEdge> result =
            new ArrayList<GeomPlanarGraphDirectedEdge>();
        AStarNodeWrapper x = n;
        while (x.cameFrom != null)  {
            result.add(0, x.edgeFrom); // add this edge to the front of the list
            x = x.cameFrom;
        }

        return result;
    }

    /**
     * /////////////////////////// Euclidean Distance ////////////////////////////
     * Measure of the estimated distance between two Nodes. Extremely basic, just
     * Euclidean distance as implemented here.
     * @param x
     * @param y
     * @return notional "distance" between the given nodes.
     */
    double heuristic(Node x, Node y)    {
        Coordinate xnode = x.getCoordinate();
        Coordinate ynode = y.getCoordinate();
        return Math.sqrt(Math.pow(xnode.x - ynode.x, 2)
            + Math.pow(xnode.y - ynode.y, 2));
    }

    /**
     * //////////////////////////// Road Length //////////////////////////////////
     * @param e
     * @return The length of an edge
     */
    double length(GeomPlanarGraphDirectedEdge e)    {
        Coordinate xnode = e.getFromNode().getCoordinate();
        Coordinate ynode = e.getToNode().getCoordinate();
        return Math.sqrt(Math.pow(xnode.x - ynode.x, 2)
            + Math.pow(xnode.y - ynode.y, 2));
    }

    /**
     *  //////////////////////// Nodes to Consider ///////////////////////////////
     *  Considers the list of Nodes open for consideration and returns the node
     *  with minimum fx value
     * @param set list of open Nodes
     * @return
     */
    AStarNodeWrapper findMin(ArrayList<AStarNodeWrapper> set)   {
        double min = 100000;
        AStarNodeWrapper minNode = null;
        for (AStarNodeWrapper n : set)  {
            if (n.fx < min) {
                min = n.fx;
                minNode = n;
            }
        }
        return minNode;
    }

    /**
     * 
     * /////////////////////////// A* Node Meta Info /////////////////////////////
     * A wrapper to contain the A* meta information about the Nodes
     *
     */
    class AStarNodeWrapper  {
        // the underlying Node associated with the metainformation
        Node node;
        // the Node from which this Node was most profitably linked
        AStarNodeWrapper cameFrom;
        // the edge by which this Node was discovered
        GeomPlanarGraphDirectedEdge edgeFrom;
        double gx, hx, fx;

        public AStarNodeWrapper(Node n) {
            node = n;
            gx = 0;
            hx = 0;
            fx = 0;
            cameFrom = null;
            edgeFrom = null;
        }
    }
}

Polygon.java

package sim;

import sim.util.geo.MasonGeometry;
import java.util.ArrayList;

/**
 * Polygon.java
 *
 * Copyright 2011 by Sarah Wise, Mark Coletti, Andrew Crooks, and
 * George Mason University.
 *
 * Licensed under the Academic Free License version 3.0
 *
 * See the file "LICENSE" for more information
 *
 * $Id: Polygon.java 842 2012-12-18 01:09:18Z mcoletti $
 */
public class Polygon extends MasonGeometry  {
    String soc;

    ArrayList<Polygon> neighbors;

    public Polygon()    {
        super();
        neighbors = new ArrayList<Polygon>();
    }

    public void init()  {
        soc = getStringAttribute("RC_RankCol");
    }

    String getSoc() {
        if (soc == null)    {
            init();
        }
        return soc;
    }
}


Комментарии
1 ответ

Чувак... с чего начать. Мне даже трудно как-то группу вопросов. Я буду просто идти построчно, я думаю... ну и оговорка: если сарказм нашел, сохранить ее. И это будет своего рода комментарий код я дам моих коллег. Добро пожаловать в реальный мир, я думаю.

MK_7

Совсем плохо именования по всему коду. Что MK_7 должно означать? Седьмой уровень Грибное Королевство? Весьма необычные пасхальные яйца, но для начала, не делая ваш доктор, человек.

Комментарии

Это самое страшное:

//////////////////////////////////////////////////////////////////////////////
///////////////////////////// MODEL PARAMETERS ///////////////////////////////
//////////////////////////////////////////////////////////////////////////////

Это просто бесполезно. Это не только бесполезно, я понятия не имею, что я должен делать с этой информацией. И это неправильно. Первая строка после этого комментария является serialVersionUID. И это не параметры. Просто избавиться от всех этих комментариев, это просто беспорядок и ввести в заблуждение.

serialVersionUID

Отключить затмение предупреждение для serialVersionUID. И удалить все тех жидкости. Когда я парное программирование с моими учениками, я запрещаю им использовать быстро исправить. Потому что они не знают о том, какие ошибки/предупреждения, и то, что быстрого решения нет.

общие переменные

Не Взорви реализации деталь:
общественные GeomVectorField дорог = новый GeomVectorField();

Смотрите сокрытие информации

другой комментарий

Ладно, я отзываю свое предыдущее заявление, это самое худшее:

/**
* //////////////////////// Model Constructor ////////////////////////////////
* Model Constructor
*/

Javadoc с одном комментарии.

Разработке интерфейсов

Не объявлять переменные при реализации структура данных, использовать Map вместо HashMap. Это не должно тебя касаться, какой тип карты. Решение какие карты использовать, принимается один раз.

<> Оператор / алмаза

вместо

ArrayList<agents.MainAgent> agentList = new ArrayList<agents.MainAgent>();

писать

ArrayList<agents.MainAgent> agentList = new ArrayList<>();

Код закомментирован

Сделать репозиторий кода. И никогда не проверить в комментарии код. Если есть закомментированный код, никто никогда не узнает, если это важно. Если вам нужны истории, вы получили его в вашем СКМ.

Setup() метод

Король худшем получает новый претендент:

/**
* //////////////////////// OSVI Polygon Setup ///////////////////////////////
* Polygon Setup
*/
void setup()

Просто имя метода polygonSetup и избавиться от этого комментария.

И вот этот:

    // copy over the geometries into a list of Polygons

Ну, почему бы вам не назвать Способ copyGeomtriesIntoPolygons? Кроме того:

polys.addAll(world.getGeomtries())

нормально. (Не переусердствуйте способ сцепления, правда)

метод start()

... Вы называете его начала, но комментарий говорит "модель инициализация". (Дважды, кстати). Какой из них правильный?


    /*
src/
data/
.shp, .dbf, .csv ...
sim/
MK_7/
.java files
*/

Первый: ВТФ? (Вы знаете, лучшей измерения код благость ВТФ в минуту.)

Во-вторых: эти файлы не должны быть в src/данных. Это не исходный код.


        URL roadsFile = MK_7.class.getResource
("/data/Final_ITN.shp");

... так что ваша программа работает только с отгруженной ресурсов и нет возможности использовать другие данные?


ShapeFileImporter.read(roadsFile, roads);

Быть более ясным о том, что Вы читаете. И если Вы читаете что-то на что-то, сделать метод имя. И почему метод start() чтение данных? Это из-за комментария (модель инициализации) является более правильным, чем имя метода?


System.out.println("    Roads shapefile: " +roadsFile);

Использовать API журналирования.


Envelope MBR = roads.getMBR();

Конвенций код: переменные не должны быть в верхнем регистре. Смотрите Java-код convetions


MBR.expandToInclude(world.getMBR());

Разверните, что включать и что? Почему "конверт МБР" - которые вы получили от дороги - должны быть дополнены "мира.getMBR()"?

// read in the FZ3 file

Извлечь код, который читает в ФЗ [3] файл в отдельный метод и вызывать его readFZ3File. И избавиться от комментария.


setup();

Итак, начало()/"модель инициализации" метод вызова setup метод. ВТФ++


agentGoals("/data/AgentGoals.csv");

Имена методов должны иметь глагола в нем. И о том, что он делает: он инициализирует агентов и читает CSV-файл файл. Правильное название будет readAgentGoalsAndInitialize. И если имя имеет and в его имя, он обычно не слишком много. Я должен сделать только одну вещь.


System.out.println();
System.out.println("Starting simulation...");

Никаких причин не использовать \N для линии подачи...


roads.setMBR(MBR);

Зачем вам загружать все основные загрузочные записи, то так много других вещей, и затем установить в MBR в других видах?


System.out.println("Error: missing required data file");

и

e.printStackTrace();

1-й: использовать API журналирования.
2-й: будьте последовательны.

отделка()

 * //////////////////////// Model Finish & Cleanup ///////////////////////////

Врун. Метод Setup() метод очистки. По крайней мере, зачистка агентов.

agentGoals()

Использовать try-с-ресурсами блока.


for (String data : splitted)
agentGoalsResult.add(data);

Я рекомендую использовать скобки. Я никогда не видела линий кода, где нет-кронштейн-один-лайнер-рюшечки (как это называется?) допускается.


populateAgent()

 * //////////////////////// Setup mainAgent //////////////////////////////////

... заполнить или подстава? ...

 * Read in the population files and create appropriate populations

... или это readPopulationFilesAndCreatePopulations?


Не забудьте закрыть свои ресурсы


String homeTract = bits[3];

Что дома Трактор?


String ROAD_ID = bits[3];

-> это roadId_s_. верблюжьего, и это множественное число.


Random randomiser = new Random();

Читать конструктору документации случайных. Если созданный в рамках той же системы.currentTimeMillis(), он будет использовать те же семена. Кроме того, я видел случайная величина где-то, почему бы не использовать это?


String random = csvData.get(new Random().nextInt(csvData.size()));

Случайных что?

String goalTract = random;

Почему объявления random в первую очередь?


for (int i = 0; i < pop; i++)   {

что такое поп?


agents.MainAgent a

Что такое a? Similator к b?


continue; // DON'T ADD IT if it's bad

НЕ ДОБАВИТЬ, ЧТО ЕСЛИ ЧТО ПЛОХО?


newGeometry.isMovable = true;

Как говорили раньше: не подвергайте деталь реализации.


d.close();

... это было ужасно много времени, чтобы выяснить, что d это. Думаю, что это было? А BufferedReader конечно. Это логично.


Iterator<?> nodeIterator

В моем opinition, тип безопасности-это хорошая вещь (я ненавижу яваскрипт). Использовать Iterator<Node> в качестве параметра тип.


@SuppressWarnings("unused")

... Вот еще один пример быстрого затмение исправить. Чувак, если он не используется, удалите его. Не подавить предупреждение.


Ну и почему вы декларируя coord (координата какой, кстати?) и point (как, кстати?) не в цикле while?

метод main()

doLoop(MK_7.class, args);

... кодекса doLoop не выложили, но передачей класса выглядит довольно подозрительно.


System.exit(0);

Чувак, это код выхода по умолчанию...

MK_7WithUI.java

Господи, это не останавливает.

Ну, MK_7WithUI указывает, что данный тип будет делать, чтобы много, слово "с" обычно указывается, что...


/////////////////////////// DISPLAY FUNCTIONS ////////////////////////////////

Ну, мы называем это методы в Java


 * ///////////////////////// Default constructor /////////////////////////////

Врун. Это не конструктор по умолчанию. Видеть конструктор по умолчанию.

setupPortrayals()

sim.MK_7 world = (sim.MK_7) state;

Я не понимаю: почему государство в мире?


display.reset();

настройка изображения не сбрасывается на дисплее

метод main()

Как правило, основным методом является на дне типа.


Console c = new Console(simple);

Тю, какая консоль? Консоль-консоль? Почему он передает, что мк7 с штучку пользовательского интерфейса?

c.setVisible(true);

ЖДАТЬ ЧЕГО?

Ну, в консоли код не выложили, но если эта штука на самом деле является JFrame или что-то, ты ружие сделать меня по-настоящему разозлил.

getSimulationInspectedObject()

*  This must be included to have model tab, which allows mid-simulation
* modification of the coefficients

Вы должны были видеть взгляд на моем лице. Почему должно что быть включено что чтобы чего-то не имеет ничего общего с именем метода?

Зачем его возвращать объект?

Почему существует явный комментарий о энергонезависимой?

Все.. просто.. так страшно

начать()

     * Called when starting a new run of the simulation. Sets up the portrayals
* and chart data.

Оооо мне как-то кажется, что это лживый комментарий. И да, это. Он также удаляет серии из графика движения, делает какие-то причудливые скорость изменения штучку и schedlung какой-то и расчет средней скорости (О и документации в рамках методов Иисус Христос), и влияет ли как-то настроить интерфейс.


double maxS = 0, minS = 10000, avgS = 0, count = 0;

Пожалуйста, не делайте этого. Объявлять переменные строка за строкой.
Кстати, что s? В математике и физике, обычно называется скоростью.


if (a.reachedGoal)  {
continue;
}

Обратное состояние и снять продолжения. И я не знаю,... я обычно передергивает, когда я вижу continue. Напоминает мне мои уроки ассемблер как-то. Не знаю, почему, я стараюсь забыть об этом.


 avgS += speed;

... Ну, на самом деле это не средняя скорость. Средняя будет рассчитываться после цикла фур.


double time = state.schedule.time();

Следует gettime () так. Время() читается как "остановить время" или "время-то".


    roadsPortrayal.setPortrayalForAll(new GeomPortrayal(Color.DARK_GRAY, 0.0005, false));

Что 0.0005? Что ложь?

PolyPortrayal

Есть ли причина, чтобы использовать внутренние классы?

ничья()

Переключатель также работает на строки (начиная с версии JDK 1.7, я думаю)

MainAgent

Чувак, у меня есть для прокрутки, чтобы увидеть все переменные. Что типа слишком долго. поглядывает и проверяет полосу прокрутки. Оно слишком длинное.


private double basemoveRate = 10.0;
private double moveRate = basemoveRate;

basemoveRate никогда не используется повторно. Кроме того, он должен быть постоянным:
частная статические заключительные BASE_MOVE_RATE = 10.0;


private LengthIndexedLine segment = null;

Это как
Точка провода = нуль;

Как на земле я знаю, что wire это момент, когда я вижу семь миллионов строк в коде?


static private GeometryFactory fact = new GeometryFactory();

То же и здесь. Позже:

location = new MasonGeometry(fact.createPoint(new Coordinate(10, 10))) ;

Как бы я знаю, что fact не факт, но фабрика?


// Now set up attributes for this agent

"Давным-давно" (ок, может быть, я стал немного глупо сейчас)


//////////////////////////// AGENT ATTRIBUTES ////////////////////////////////

... и первым делом после что комментарий-это добытчик ...


метод gettype()

Почему на земле это MainAgent'ы работу, управлять автомобилем типа в любом случае? И почему тип автомобиля, хранящиеся в location.

findNewAStarPath()

   if (currentJunction == null) {
return; // just a check
}

Да, просто проверить, но, выпрыгнув из метода.

прогресс()

Progessing что? Что Вэл? Какое это возвращение? Используется сочетание клавиш Ctrl+F и скорости? Что?

шаг()

currentIndex += speed;

Что есть индекс, чтобы сделать со скоростью?


if (linkDirection == 1 && currentIndex > endIndex)   {

Почему 1? Почему currentIndex быть больше, чем индекс, чтобы выполнить этот код?


{ // just update the position!

Вы злитесь писать этот кусок кода?

flipPath()

/**
* ////////////////////////// Flip Agent's Route //////////////////////////////
* Flip the agent's path around
*/

Флип путь, флип маршрута, вернуться pathDirection, вернуться linkDirection. Это как тезаурус здесь.

Астар И Многоугольные

Ладно, я думаю, я должен остановиться здесь и сейчас...

Руководство

Хорошо. Он взял меня так долго, мне пришлось взять два тормоза сигареты.

Смотрите, это довольно сложная тема, что и ты. Теперь, у вас есть сложный вопрос, и сложный код. Это обязанность разработчика программного обеспечения, чтобы написать чистый код, так что читатель может сосредоточиться на теме. ОК?

Чистый Код

Используйте правильные отступы. Форматировать ваш код. Не оставляйте комментарии код. Избавиться от "все" замечания и сделать ваш код говорит сам за себя. Используйте общие правила кодекса.

Читать книгу "Чистый код" Роберта С. Мартина. Там должен быть бесплатный PDF-версии. Я очень рекомендую эту книгу. Многие из моих пунктов в данном обзоре также содержатся в книге и рассмотрены очень подробно.

Другое дело: хороший код, или чистый код, трудно измерить. Но если кто-то еще открывает его и думает, что такие вещи, как "О, это мило", это хорошо. Мое любимое: "этот код сексуальный". Вам нужно дать себе это.

ООП

У вас есть прикладом тонны кода, разложил в несколько классов. Вы действительно должны прочитать о принципах ООП. Есть так много priniples и моделей, которые могут быть применены к коду. (Конечно, ООП-это не про разделение кода на классы просто имеют меньшие классы.) Возможно, вы захотите прочитать о твердых принципах и о высокой сплоченности и теряют сцепление. Но из моего опыта, просто читать об этом не слишком полезно.

Становится лучше

О производстве "хороший код", я узнал, что должен делать парное программирование и код комментариев с хорошим, страстным и опытным программистам. Да, этот сайт называется отзыв код, но, вы знаете, лицом к лицу общение-лучшее общение. Итак, принципиальная разница между ревью кода и пара программ - ну, хотя бы с образовательной точки зрения - это, что код, отзыв больше о поиске багов, мелких деталей, как "это может быть статический метод", "есть", "я считаю, что слишком сложные". Парное программирование с другой стороны-это больше про "процесс мышления" и "решения". Если вы делаете обзор, и вы видите, что другой чувак, например, ставит "х" и " Y " в виде Point. Вам не судить об этом. Но если у вас парного программирования, он скажет вам, что они "принадлежат друг другу".

Рабочий код

Если вы закончили свою работу, толкать его вверх к вашему СКМ, и ты думаешь "этот код работает, я сделал.", У меня плохие новости: это только половина вашей работы. В реальности, чаще вы будете читать больше кода, чем вы пишете. Если это займет у вас два дня, чтобы читать и анализировать чистый код, он может легко захватить вас четыре дня, чтобы прочитать плохой код. И в реальности, что какашки кучу денег впустую.

Тесты

Вы не размещать какие-либо тесты, и я уверен, что таких нет. Вы знаете, почему? Потому что это не проверить. Я настоятельно рекомендую прочитать книги о модульном тестировании, особенно на основе тестов развития. Есть люди, которым это нравится, есть люди, которые не. Но что он будет делать, он будет производить проверяемые конструкции. Что вполне лучше, чем не проверяемые конструкции.

Теперь, почему тесты так важно? Ну, если у вас ужасный код, который должен рефакторинг, и вы можете не писать юнит-тесты, потому что это не для тестирования, как вы выяснить, если она все еще работает? Я видел классы с тысячи строк и несколько десятков внутренних классов. Я хотела переделать его. Но я не стала. Потому что это было чертовски сложно, все зависимости для каждого, чтобы все все. И если у вас есть код, который из-за денег, в смысле: если ты нарушишь это, ваш клиент будет терять деньги, и вы не на 100% уверен, что это работает, ты так чертовски страшно, вы просто оставить его.

Честными

Если бы вы представить, что кусок кода в интервью, даже свежие из Университета, вы не получите работу. Если вы не хотите иметь работу и развиваются в нашем проекте и размещать код в репозиторий, он будет обратно-сдал сразу. Затем мы сделаем много парного программирования ;-)

Надеюсь, что это помогает,

slowy

3
ответ дан 24 марта 2018 в 04:03 Источник Поделиться