实现Prim算法的策略模式

时间:2015-11-30 20:26:36

标签: java dijkstra strategy-pattern prims-algorithm

我正在使用Dijkstra的算法进行项目,但是想尝试使用策略模式实现Prims算法来查看它更好,但我不确定如何使用策略模式。我之前从未使用过模式,所以我不知道从哪里开始。

package wpi.cs509.routeFinder;

import wpi.cs509.dataModel.*;
import wpi.cs509.dataManager.*;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.PriorityQueue;

public class RouteFinder {

public static ArrayList<Point> computePaths(Point source, Graph g, Point destination)
{
    if(source.getId()==destination.getId()){
        ArrayList<Point> point=new ArrayList<Point>();
        point.add(source);
        return point;
    }
    source.minDistance = 0;
    PriorityQueue<Point> pointQueue = new PriorityQueue<Point>();
    pointQueue.add(source);

while (!pointQueue.isEmpty()) {
    Point u = pointQueue.poll();

        // Visit each edge exiting u
        for (Edge e : g.getNeighbors(u))
        {
            Point v = g.getPointById(e.getePointId()!=u.getId()?e.getePointId():e.getsPointId());
            float weight = e.getWeight();
            double distanceThroughU = u.minDistance + weight;
    if (distanceThroughU < v.minDistance) {
        pointQueue.remove(v);
        v.minDistance = distanceThroughU ;
        v.previous = u;
        pointQueue.add(v);
      //  System.out.println("u.id is"+u.getId());
            }
        }
    }
return getShortestPathTo(g.getPointById(destination.getId()));

}

public static ArrayList<Point> getShortestPathTo(Point destination)
{
    ArrayList<Point> path = new ArrayList<Point>();
    for (Point vertex = destination; vertex != null; vertex = vertex.previous)
    { 
        path.add(vertex);
    }

    Collections.reverse(path);
    return path;
}



public static void main(String[] args){
    Graph g = new Graph();
    ArrayList<Point> p = new ArrayList<Point>();
    //g=DataManager.getGraphByNameWithDB("testLab",2);
    Point source = new Point();
    source.setId(11);
    source.setX(111);
    source.setY(222);
    source.setBuildingName("testLab");
    source.setFloorNum(2);
    source.setMapEntrance(false);
    source.setDestination(true);
    source.setName("source");


    Point end = new Point();
    end.setId(15);
    end.setX(161);
    end.setY(616);
    end.setBuildingName("testLab");
    end.setFloorNum(2);
    end.setMapEntrance(false);
    end.setDestination(true);
    end.setName("end");

    p=computePaths(source,g,end);
    System.out.println(p.size());
    for(int i =0;i<p.size();i++)
    {
        System.out.println("result is "+p.get(i).getId());
    }
}
}

1 个答案:

答案 0 :(得分:0)

策略模式旨在将算法放入一个类中,其中数据保证相同,这样算法可以重用于多个数据副本,而无需创建处理它们的策略的新实例。

除非你真的需要这种行为,否则我建议你不要使用策略模式来启动,因为这会以某种方式削弱面向对象的设计(通过分离数据和行为)。

相反,尝试使用两个实现DikstraRoutePimsRoute的Route接口。然后,您的顶级代码只会处理Route,而不需要处理它们的实现。

界面

public interface Route {
   public ArrayList<Point> getPath();
}

您的构造函数可能看起来像

public DikstraRoute implements Route {
   public DikstraRoute(Point start, Graph g, Point destination) {
     ...
   }

   @Override
   public ArrayList<Point> getPath() {
     ...
   }
}

public PimsRoute implements Route {
   public PimsRoute(Point start, Graph g, Point destination) {
     ...
   }

   @Override
   public ArrayList<Point> getPath() {
     ...
   }
}

并且接口保证&#34; getPath()&#34;操作

它是一种面向对象的语言,可能想要时不时地写几个对象。全静态编程方式不会随着时间的推移为您提供任何类型的维护优势(因此它可能也是C)。

如果你发现(在点击这个中间版之后)你真的需要一个策略,那么将传递给构造函数的对象移动到界面中的方法中。剪切上一个(上面)解决方案中的所有内部字段,您将Route对象转换为Route策略。请记住,如果您的对象只包含代码但没有状态,那么它实际上就是一种策略。

为了证明,策略方法看起来像

界面

public interface Route {
   public ArrayList<Point> getPath(Point start, Graph g, Point destination);
}

您的构造函数可能看起来像

public DikstraRoute implements Route {
   public DikstraRoute() {
     ...
   }

   @Override
   public ArrayList<Point> getPath(Point start, Graph g, Point destination) {
     ...
   }
}

public PimsRoute implements Route {
   public PimsRoute() {
     ...
   }

   @Override
   public ArrayList<Point> getPath(Point start, Graph g, Point destination) {
     ...
   }
}