我的项目是关于在Java中实现hyperGraph
我的hyperGraph包含各种类型的hyperEdge,具体取决于我拥有的顶点类型
顶点类型:图片,标签...
HyperEdge =同质(同类型的相关顶点)/同质(同类型的相关顶点)
同类HyperEdge =图像-图像HyperEdge/标签-标签hyperEdge
这是一个快速绘制的UML图
这是我的代码
public interface HomogenousHyperedge< T extends Vertex<L>, L> extends Hyperedge {
public abstract List<T> searchNearstNeighborsVertex(
Hypergraph hypergraph, T vertex);
}
public class ImageImageHyperedge implements
HomogenousHyperedge<ImageVertex, Map<String,Instance>> {
@Override
public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph,
ImageVertex vertex) {
return null;
}
}
问题出在ImageImageHyperEdge类中,我应该知道基于它的要素的类型是什么,我将搜索ImageVertex最近的邻居
我无法将其传递给 super 接口(interface)的抽象方法,因为TagTagHyperEdge类不需要它
并且如果我用{featureOneHyperEdge class,... featureFiveHyperEdge class}替换ImageImageHyperEdge类(我知道要素类型)
这将是代码的重复,因为它是相同的最近邻居搜索算法
feature =图像的低级特征(例如颜色直方图)
我有5种低水平功能
我将使用每个图像来搜索当前图像中最近的邻居
所有功能都存储在一个简单的文本文件中
使用相同的算法搜索最近的邻居
每次都只更改文件
最佳答案
您的UML设计不够好。跳过难看且难以理解的“样式”,向我们展示“顶点”和“边缘”,以及关联图;而不是您的(可能过于复杂的)继承概念。
您的API,设计和基本问题尚不清楚。 “Hyperedge”类可以表示Edge的单个实例,并将其两端关联起来。或者它们可以(如果更好地命名)表示“边缘类型”,并从指定的Endpoint参数全局搜索图形。
这些是完全不同的设计,在您解决上述问题之前,您的问题是毫无意义的。
无论哪种方式,Edge.search()都没有正确的签名。其中VS和VE是起点和终点顶点类型,TE是边线类型,它应该是:
public class EdgeType {
public List<EV> getEndpoints (SV startVertex);
}
或者
public class Vertex {
public List<TE> Vertex.getEdges();
}
public class Edge {
public EV Edge.getEndpoint();
}
最近邻居算法应使用泛型类型实现,然后由具体类按要求调用(带有精确的类型签名)。
顺便说一句,当您提到“最近的邻居”时;还不清楚“最近的邻居”是指直接相连的顶点(这是微不足道的)还是要找到指定类型的最接近的顶点(如何测量距离?未指定)。
无论哪种方式,实现“Edge”子类型的实用性和正确性/需求似乎都不清楚。许多图算法发现顶点/节点很有趣,并将它们子类型化,但是我对导致这些边缘的子类型(或子类型的实用性)了解不足。
最后提示:放弃复杂的命名方式,KISS。 “顶点”和“边缘”将帮助您获得清晰,简单,易于理解和正确的设计。节省了额外的钱。
响应来自Nawara的进一步信息:
然后,这是您已建模的EdgeType,并且在询问“最近邻居”时,您应选择“起始顶点”并返回一个Edge(如果需要距离度量)或“Vertices”。
对“图形”的引用可能应该从“顶点”参数中隐含。
至于您的EdgeType继承层次结构:子类型和继承应定义为遵循行为特征,而不是它们引用的泛型类型(顶点类型)。 OO类层次结构设计的原则是建模而不是存在。
在这方面,您可能有一个KnnDistanceEdgeType和FlickrDistanceEdgeType类,作为祖先,或者,如果没有其他方法行为需要不同,则作为实际的实现类。他们要搜索的要素类型/类可以设置为属性-具有不同的属性和通用名称,以回答不同的顶点类型。
例如。
IMAGE_IMAGE_EDGES = new KnnDistanceEdgeType<ImageVertex,ImageVertex>( ImageVertex.class, ImageVertex.class);
TAG_TAG_EDGES = new FlickrDistanceEdgeType<TagVertex,TagVertex>( TagVertex.class, TagVertex.class);
ANY_EDGES = new KnnDistanceEdgeType<Vertex,Vertex>( Vertex.class, Vertex.class);
如果EdgeType中还有很多其他行为(我们尚未定义任何行为,并且无法想象太多),则可以将KNN距离和Flickr距离算法移到单独的类中。可能不需要。
记住:在OO中,子类是行为,而不是存在。并给我+1票!