2

I need to implement a graph that will have a generic type elements as nodes, and generic type elements as labels of the edges. When labels are of type Double I need to be able to calculate graph's weight.

public class Graph<V, T> { ... public Double graphWeight() { Double sum = 0; for every label T weight { sum = sum + weight; } if(!directed) sum /= 2; return sum; } } 

Can this be done somehow?

7
  • use instanceof to find out if weight is of type Double, then cast it. Commented Jun 18, 2018 at 22:50
  • Create a extension of Graph which defines the constraints as String and Double, it only makes sense to have weight when T is a numeric value Commented Jun 18, 2018 at 22:52
  • I fail to see why you would rather use generics than interfaces unless there is a need for strict enforcement of what type of nodes and edges the Graph will hold... But even so it seems like more of a hassle than the alternative. An interface allows you to create different implementations of the nodes and edges to suit your needs. Commented Jun 18, 2018 at 23:19
  • @TiagoRedaelli, it's an assignment, so I'm unfortunately forced to do it like that. Commented Jun 18, 2018 at 23:32
  • @MadProgrammer I'm unfortunately forced to implement it this way Commented Jun 18, 2018 at 23:33

2 Answers 2

3

Pass and store an instance of DoubleFunction<T> in the constructor of the graph. Then use the stored instance in the loop:

public class Graph<V, T> { ... private final DoubleFunction<T> getWeight; public Graph(DoubleFunction<T> getWeight) { this.getWeight = getWeight; } public double graphWeight() { double sum = 0; for every label T weight { sum = sum + getWeight.apply(weight); } if(!directed) { sum /= 2; } return sum; } } 

Instances of the graph are created like this:

class Edge { ... public double weight() { .. } } ... Graph<Vertex,Edge> graph = new Graph<>(Edge::weight); 
Sign up to request clarification or add additional context in comments.

5 Comments

Can this be done if I don't have an "Edge" class, but my graph is implemented as HashMap<V, HashMap<V,T>>? Sorry, I just have never seen such stuff. And thanks.
@Sepfins Assuming that you would like to "interrogate" HashMap<V,T> for a T, where would the key of type V come from? Generally, though, you can use a lambda: Graph<Vertex,Edge> graph = new Graph<>(w -> w.callThatExtractsDoubleGoesHere());
@Sepfins, You can use an adjecency matrix to represent the weight between nodes if you don't have an Edge class: en.wikipedia.org/wiki/Adjacency_matrix
@dasblinkenlight, I don't know if I undestood correctly, but "interrogation" goes something like map.get(elem1).get(elem2) where elem1 and elem2 are bothelements of type V. But in case of graphWeight() I just iterate through both HashMaps by using values().
@Sepfins If T in HashMap<V, HashMap<V,T>> is a numeric type, such as Double, Integer, or BigDecimal, you can write Graph<Vertex,BigDecimal> graph = new Graph<>(bigDec -> bigDec.doubleValue());
1

Here is a suggestion from me for what it's worth. It uses an adjacecny matrix to represent the weight which can either be an integer or a double (not sure why anyone would want this) and then a list of vertices for the nodes.

Still anything more than this should really be using interfaces for V and E.

public class Graph <V, E> { private List<V> vertices; private E[][] adjMatrix; public void setVertices(List<V> nodes) { vertices = nodes; } public void setAdjacecnyMatrix(E[][] adjMatrix) { this.adjMatrix = adjMatrix; } public Object getNode(int index) { return vertices.get(index); } public boolean hasEdge(int srcs, int dest) { for (int v = 0; v < vertices.size(); v++) { if (adjMatrix[srcs][dest] instanceof Integer && (Integer) adjMatrix[srcs][dest] > 0) return true; if (adjMatrix[srcs][dest] instanceof Double && (Double) adjMatrix[srcs][dest] > 0) return true; } return false; } public double graphWeight() { double sum = 0; int numV = vertices.size(); for (int s = 0; s < numV; s++) { for (int v = 0; v < numV; v++) { if (adjMatrix[s][v] instanceof Double) { sum += (Double) adjMatrix[s][v]; } else if (adjMatrix[s][v] instanceof Integer) { sum += (Integer) adjMatrix[s][v]; } } } return sum; } } public static void main(String[] args) { Graph<String, Double> g = new Graph(); String[] nodes = {"A", "B", "C"}; Double[][] adjMatrix = { {0., 1., 3.}, {1., 0., 2.}, {3., 2., 0.}}; g.setVertices(Arrays.asList(nodes)); g.setAdjacecnyMatrix(adjMatrix); System.out.println("g1: " + g.graphWeight()); Graph<String, Integer> g2 = new Graph(); Integer[][] adjMatrix2 = { {0, 1, 4}, {1, 0, 2}, {4, 2, 0}}; g2.setVertices(Arrays.asList(nodes)); g2.setAdjacecnyMatrix(adjMatrix2); System.out.println("g1: " + g2.graphWeight()); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.