2015-06-28 3 views
1

Я пытаюсь использовать Spark GraphX ​​и сталкиваясь с тем, что, по моему мнению, является проблемой в том, как я использую Scala. Я новичок в Scala и Spark.scala «не является членом параметра типа»

создать граф с помощью вызова своей собственной функции:

val initialGraph: Graph[VertexAttributes, Int] = sim.createGraph 

VertexAttributes это класса я определил:

class VertexAttributes(var pages: List[Page], var ads: List[Ad], var step: Long, val inDegree: Int, val outDegree: Int) 
extends java.io.Serializable 
{ 
    // Define alternative methods to be used as the score 
    def averageScore() = 
    { 
    this.ads.map(_.score).sum/this.ads.length 
    } 

    def maxScore() = 
    { 
    if(this.ads.length == 0) None else Some(this.ads.map(_.score).max) 
    } 

    // Select averageScore as the function to be used 
    val score = averageScore _ 
} 

После некоторых вычислений, я использую вершины Graphx(), чтобы получить оценки для каждой вершины:

val nodeRdd = g.vertices.map(v => if(v._2.score() == 0)(v._1 + ",'0,0,255'") else (v._1 + ",'255,0,0'")) 

Но это не будет компилироваться, сообщение SBT является:

value score is not a member of type parameter VertexAttributes 

У меня есть сообщение об ошибке в этой ошибке, но, честно говоря, я не могу следовать за разговором. Может кто-нибудь объяснить причину ошибки и как я могу это исправить?

спасибо.

P.S. Ниже приведен код для метода createGraph:

// Define a class to run the simulation 
class Butterflies() extends java.io.Serializable 
{ 
    // A boolean flag to enable debug statements 
    var debug = true 

    // A boolean flag to read an edgelist file rather than compute the edges 
    val readEdgelistFile = true; 

    // Create a graph from a page file and an ad file 
    def createGraph(): Graph[VertexAttributes, Int] = 
    { 
    // Just needed for textFile() method to load an RDD from a textfile 
    // Cannot use the global Spark context because SparkContext cannot be serialized from master to worker 
    val sc = new SparkContext 

    // Parse a text file with the vertex information 
    val pages = sc.textFile("hdfs://ip-172-31-4-59:9000/user/butterflies/data/1K_nodes.txt") 
     .map { l => 
     val tokens = l.split("\\s+")  // split("\\s") will split on whitespace 
     val id = tokens(0).trim.toLong 
     val tokenList = tokens.last.split('|').toList 
     (id, tokenList) 
     } 
    println("********** NUMBER OF PAGES: " + pages.count + " **********") 

    // Parse a text file with the ad information 
    val ads = sc.textFile("hdfs://ip-172-31-4-59:9000/user/butterflies/data/1K_ads.txt") 
     .map { l => 
     val tokens = l.split("\\s+")  // split("\\s") will split on whitespace 
     val id = tokens(0).trim.toLong 
     val tokenList = tokens.last.split('|').toList 
     val next: VertexId = 0 
     val score = 0 
     //val vertexId: VertexId = id % 1000 
     val vertexId: VertexId = id 
     (vertexId, Ad(id, tokenList, next, score)) 
     } 
    println("********** NUMBER OF ADS: " + ads.count + " **********") 

    // Check if we should simply read an edgelist file, or compute the edges from scratch 
    val edgeGraph = 
    if (readEdgelistFile) 
    { 
     // Create a graph from an edgelist file 
     GraphLoader.edgeListFile(sc, "hdfs://ip-172-31-4-59:9000/user/butterflies/data/1K_edges.txt") 
    } 
    else 
    { 
     // Create the edges between similar pages 
     // Create of list of all possible pairs of pages 
     // Check if any pair shares at least one token 
     // We only need the pair id's for the edgelist 
     val allPairs = pages.cartesian(pages).filter{ case (a, b) => a._1 < b._1 } 
     val similarPairs = allPairs.filter{ case (page1, page2) => page1._2.intersect(page2._2).length >= 1 } 
     val idOnly = similarPairs.map{ case (page1, page2) => Edge(page1._1, page2._1, 1)} 
     println("********** NUMBER OF EDGES: " + idOnly.count + " **********") 

     // Save the list of edges as a file, to be used instead of recomputing the edges every time 
     //idOnly.saveAsTextFile("hdfs://ip-172-31-4-59:9000/user/butterflies/data/saved_edges") 

     // Create a graph from an edge list RDD 
     Graph.fromEdges[Int, Int](idOnly, 1); 
    } 

    // Copy into a graph with nodes that have vertexAttributes 
    //val attributeGraph: Graph[VertexAttributes, Int] = 
    val attributeGraph = 
     edgeGraph.mapVertices{ (id, v) => new VertexAttributes(Nil, Nil, 0, 0, 0) } 

    // Add the node information into the graph 
    val nodeGraph = attributeGraph.outerJoinVertices(pages) { 
     (vertexId, attr, pageTokenList) => 
     new VertexAttributes(List(Page(vertexId, pageTokenList.getOrElse(List.empty), 0)), 
         attr.ads, attr.step, attr.inDegree, attr.outDegree) 
    } 

    // Add the node degree information into the graph 
    val degreeGraph = nodeGraph 
    .outerJoinVertices(nodeGraph.inDegrees) 
    { 
     case (id, attr, inDegree) => new VertexAttributes(attr.pages, attr.ads, attr.step, inDegree.getOrElse(0), attr.outDegree) 
    } 
    .outerJoinVertices(nodeGraph.outDegrees) 
    { 
     case (id, attr, outDegree) => 
     new VertexAttributes(attr.pages, attr.ads, attr.step, attr.inDegree, outDegree.getOrElse(0)) 
    } 

    // Add the ads to the nodes 
    val adGraph = degreeGraph.outerJoinVertices(ads) 
    { 
     (vertexId, attr, ad) => 
     { 
     if (ad.isEmpty) 
     { 
      new VertexAttributes(attr.pages, List.empty, attr.step, attr.inDegree, attr.outDegree) 
     } 
     else 
     { 
      new VertexAttributes(attr.pages, List(Ad(ad.get.id, ad.get.tokens, ad.get.next, ad.get.score)),   
           attr.step, attr.inDegree, attr.outDegree) 
     } 
     } 
    } 

    // Display the graph for debug only 
    if (debug) 
    { 
     println("********** GRAPH **********") 
     //printVertices(adGraph) 
    } 

    // return the generated graph 
    return adGraph 
    } 
} 
+0

Добро пожаловать в SO! Можете ли вы дать короткую, автономную программу в соответствии с [sscce.org] (http://sscce.org/)? Как бы то ни было, эта ошибка довольно очевидна - 'g.vertices' возвращает список кортежей (и я угадываю здесь) - первый элемент в кортеже - это« VertexAttribute », а второй - позиция« index ». Вероятно, вы захотите сделать это: 'v._1.score', а не' v._2.score'. –

+0

Спасибо, что ответили. Подпись для вершин: вершины val: VertexRDD [VD] Подпись для графика: класс Graph [VD, ED] Так что вершины возвращают RDD из VertexAttributes –

+1

Это примерно работает для меня. Можете ли вы опубликовать более полный пример? Кажется, что вы устанавливаете тип VertexAttribute где-то, который затеняет ваш класс. –

ответ

0

VertexAttributes в коде относится к параметру типа, а не к VertexAttributes класса. Вероятно, ошибка в вашей функции createGraph. Например, это может выглядеть так:

class Sim { 
    def createGraph[VertexAttributes]: Graph[VertexAttributes, Int] 
} 

или:

class Sim[VertexAttributes] { 
    def createGraph: Graph[VertexAttributes, Int] 
} 

В обоих случаях у вас есть параметр типа под названием VertexAttributes. Это то же самое, как если бы Вы писали:

class Sim[T] { 
    def createGraph: Graph[T, Int] 
} 

компилятор не знает, что T имеет метод score (потому что он не делает). Вам не нужен этот параметр типа. Просто напишите:

class Sim { 
    def createGraph: Graph[VertexAttributes, Int] 
} 

Теперь VertexAttributes будет относиться к классу, а не локального параметра типа.

+0

Спасибо за объяснение того, как параметр типа может непреднамеренно закрашиваться. Однако, я проверил свой код, думал, что нашел конструкцию, как то, что вы описали, но я все равно получаю ту же ошибку компилятора. Может, я допустил ошибку параметра типа в менее очевидной форме? Я добавил свой код createGraph в свой первоначальный вопрос. Если бы вы взглянули на него, я очень благодарен за помощь. Благодарю. –

+0

Я не вижу ничего плохого в коде. Я бы рекомендовал удалить кучу вещей, пока у вас не будет нескольких строк, которые воспроизводят проблему. В этот момент вы, вероятно, увидите, что проблема сама! По крайней мере, такой подход я бы взял, если бы у меня было время. Удачи! –

+0

Еще раз спасибо за помощь. По крайней мере, сейчас у меня есть представление о том, что искать. –

Смежные вопросы