9

我的项目是关于在 java 中实现 hyperGraph

我的 hyperGraph 包含各种类型的 hyperEdge,具体取决于我拥有的顶点类型

顶点类型:图像,标签...

HyperEdge =同质(相同类型的相关顶点)/异构(不同类型的相关顶点)

同构HyperEdge = Image-image HyperEdge/Tag-tag 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 最近邻居我无法将其传递给超级接口的抽象方法,因为 TagTagHyperEdge 类不需要它

如果我用 {featureOneHyperEdge class ,...featureFiveHyperEdge class } (我知道特征类型)替换 ImageImageHyperEdge 类,它将是重复的代码,因为它是相同的最近邻搜索算法


特征=图像的低级特征(例如颜色直方图)
我有 5 种低级特征
我将使用每一种来搜索我当前图像的最近邻居
所有特征都存储在一个简单的文本文件
中使用相同的算法搜索最近的邻居
,每次只更改文件

4

3 回答 3

1

您的 UML 设计不够好。跳过丑陋且难以阅读的“样式”,向我们展示“顶点”和“边缘”,以及关联图;不是您(可能过于复杂)的继承想法。

您的 API、设计和基本问题不是很清楚。'Hyperedge' 类可以表示 Edge 的单个实例,并将其两端关联起来;或者它们可以(如果更好地命名)表示边缘类型,并从指定的端点参数全局搜索图形。

这些是完全不同的设计,在您弄清楚以上内容之前,您的问题毫无意义。

无论哪种方式, 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,当询问“最近的邻居”时,您应该使用 Start Vertex 并返回 Edge(如果您需要距离度量)或 Vertices。

对“Graph”的引用可能应该从 Vertex 参数中隐含。

至于您的 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票!

于 2013-05-02T09:02:17.923 回答
0

根据您写的关于“功能”的内容,我会说这适合作为 ImageImageHyperEdge 类中的一个字段。您可以使用将定义它的任何各种成员来创建 FeatureType 类。

public class ImageImageHyperedge implements
   HomogenousHyperedge<ImageVertex, Map<String,Instance>> {

   private FeatureType featureType;

   @Override
   public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph,
        ImageVertex vertex) {
      return null;
   }
}
于 2013-04-17T19:40:38.550 回答
0

试试这样的东西?

public abstract class BaseFeatureHyperEdge {

    @Override
   public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph,
        ImageVertex vertex) {   
      // implement nearest neighbor search algorithm
      // and call getFeatureType where you need it.
      // This will allow you to have the search algorithm only in one place. 
      //But make the search based on the feature type;
   }

   protected FeatureType getFeatureType();
}

public class FeatureOneHyperEdge extends BaseFeatureHyperEdge{

    @Override
    protected FeatureType getFeatureType() {
        return new FeatureTypeOne();
    }
}


public class FeatureTwoHyperEdge extends BaseFeatureHyperEdge{

    @Override
    protected FeatureType getFeatureType() {
        return new FeatureTypeTwo();
    }
}

也许您可以尝试模板方法模式

于 2013-04-17T19:53:51.013 回答