在图的顶点和中应用记忆

时间:2018-12-12 00:04:57

标签: java optimization graph memoization

背景: 在我要上的一堂课中,我完成了以下任务:给出一个Pairs 的空映射和一个有向图,将每个图的顶点以及与之对应的所有顶点的总和存储在映射中从那里可以到达。我递归完成了作业。但是,我考虑过使用记忆化来改进算法。

问题:如何使用“记忆化”来改进此算法?值得这样做吗?

我的问题是我不知道该怎么做,因为每个顶点都有一组不同的顶点相连。 我尝试创建一个包含2个顶点及其值之间的Edge的Map,但是一旦到达sumRec()内部的foreach,我就不知道如何实际实现它。 (我已注释了与此尝试相关的代码,以便您可以看到我的尝试。这些注释以@Attempt开头,因此您应该能够快速发现它们)

代码:

由于不允许我上载类的库或我提交的代码,因此我快速移植了复制问题所需的所有内容。

顶点类:

import java.util.ArrayList;
import java.util.List;

public class Vertex {

    public int value;
    public String name;
    public List<Edge> edges;

    public Vertex(String name, int value) {

        this.value = value;
        this.name = name;
        edges = new ArrayList<Edge>();
    }

    public void addEdge(Edge e) {

        this.edges.add(e);
    }

    public boolean equals(Object o) {

        if(o instanceof Vertex) {

            Vertex v = (Vertex) o;
            return v.name.equals(this.name) && (v.value == this.value);
        }

        return false;
    }

    public String toString() {

        return "(" + this.name + " := " + this.value + ")";
    }

}

边缘类:

public class Edge {

    public Vertex start;
    public Vertex end;

    public Edge(Vertex start, Vertex end) {

        this.start = start;
        this.end   = end;
    }

    public String toString() {

        return start.toString() + "-->" + end.toString();
    }
}

DirectedGraph类:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class DirectedGraph {

    public List<Vertex> vertices;

    public DirectedGraph() {

        this.vertices = new ArrayList<Vertex>();
    }

    public List<Vertex> getVertices() {

        return this.vertices;
    }

    public void addVertex(Vertex v) {

        this.vertices.add(v);
    }

}

Main类(这里有main()和我的算法。通过示例显示)

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lib.DirectedGraph;
import lib.Edge;
import lib.Vertex;

public class Main {
    // @Attempt
    //static Map<Edge, Integer> memoization;

    public static int sumRec(Vertex v, List<Vertex> visited) {

        if(visited.contains(v)) 
            return 0;

        int sum = v.value;
        List<Edge> edges = v.edges;
        visited.add(v);
        // @Attempt I got stuck here 
        for(Edge e : edges) {

            sum += sumRec(e.end, visited);
        }

        return sum;
    }

    public static Map<Vertex, Integer> sumVertices(DirectedGraph g) {

        Map<Vertex, Integer> sumMap = new HashMap<Vertex, Integer>();
        List<Vertex> vertices = g.getVertices();

        for(Vertex v : vertices) {

            List<Vertex> visited = new ArrayList<Vertex>();
            int sum = sumRec(v, visited);
            sumMap.put(v, new Integer(sum));            
        }

        return sumMap;
    }

    public static void main(String args[]) {

        // @Attempt
        // memoization = new HashMap<Edge, Integer>(); 
        //   /<--------------\
        //  v1 -> v2 -> v3 -> v4
        //  \ v5
        // (Result doesn't need to be in any specific order)
        // Expected: {<v1, 15>, <v2, 15>, <v3, 15>, <v4, 15>, <v5, 5>}
        // Result:{(v1 := 1)=15, (v4 := 4)=15, (v5 := 5)=5, (v3 := 3)=15, (v2 := 2)=15}
        Vertex v1 = new Vertex("v1", 1);
        Vertex v2 = new Vertex("v2", 2);
        Vertex v3 = new Vertex("v3", 3);
        Vertex v4 = new Vertex("v4", 4);
        Vertex v5 = new Vertex("v5", 5);

        Edge e1 = new Edge(v1, v2);
        Edge e2 = new Edge(v2, v3);
        Edge e3 = new Edge(v3, v4);
        Edge e4 = new Edge(v1, v5);
        Edge e5 = new Edge(v4, v1);

        v1.addEdge(e1);
        v1.addEdge(e4);
        v2.addEdge(e2);
        v3.addEdge(e3);
        v4.addEdge(e5);

        DirectedGraph g = new DirectedGraph();

        g.addVertex(v1);
        g.addVertex(v2);
        g.addVertex(v3);
        g.addVertex(v4);
        g.addVertex(v5);

        System.out.println(sumVertices(g));

    }

}

谢谢。

0 个答案:

没有答案