修改自定义数据结构的数据

时间:2015-09-22 02:20:32

标签: c++ search data-structures graph

我有一个输入文件,我试图解析它以执行DFS,最佳优先搜索,A *搜索等操作。 它看起来像这样:

| The vertical bar denotes comments. Ignore.
|
| The first non-comment line contains N, the number of nodes in the graph.
5
| The second non-comment line contains the unique start node.
0
| The third non-comment line contains a single goal node.
3
| The fourth non-comment line specifies the number of heuristics.
1
| The fifth non-comment line starts the edge-cost adjacency matrix. [i,j] in the matrix represents the weight of the edge from node i to node j.
* 1 2 * *
* * 3 * *
* * * 5 4
* * * * *
* * * * *
| After the adjacency matrix, the heuristic evaluation vectors are given, 
| where each row containing the heuristic value h(n) for a node n
3
6
1
0

对于代码,我为Adjacency列表中的节点创建了一个类,并为该图创建了一个类。我设法解析除了最后一个输入之外的所有输入,即启发式评估数字。这是我的代码:

class AdjListNode
{
private:
    int v; // vertex or node number.
    int weight; // weight on edge to reach a particular vertex.
    int h; // a heuristic number for every node.

public:
    AdjListNode(int _v, int _w) { v = _v; weight = _w;}
    int getV() { return v;} // return the vertex number
    int getWeight() {return weight;}
    void setH(int _h) { h = _h;}
    int getH() { return h;}

};


class Graph
{
private:
    int V; // Total number of nodes/vertices in the graph
    list<AdjListNode> *adj; // a list for storing all the nodes
    //A helper function for Depth-First Search DFS.
    bool DFSUtil(int v, bool visited[], int goal, int cost);
public:
    Graph(int V);
    void DFS(int v, int goal); // Depth First Search
    void addEdge(int i, int j, char* val); // Add edge between i and j
                                           // of weight val.

    //Print the adjacency list;
    void printList();
};

void Graph::printList()
{
    list<AdjListNode>::iterator i;
    for (int j = 0; j < V; j++)
    {   
        for (i = adj[j].begin(); i != adj[j].end(); i++)
        {
            AdjListNode node = *i;
            cout << node.getV() << " ";
        }
        cout << endl;
    }
}

Graph::Graph(int V)
{
    this->V = V;
    adj = new list<AdjListNode>[V];
}


void Graph::addEdge(int u, int v, char* val)
{
    int weight = atoi(val);
    AdjListNode node(v, weight);
    adj[u].push_back(node);

}


bool Graph::DFSUtil(int v, bool visited[], int goal, int cost)
{
    visited[v] = true;

    if (v == goal)
    {
        cout << "cost is : " << cost << endl;
        cout << "path is : ";
        return true;
    }

    list<AdjListNode>:: iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); i++)
    {
        AdjListNode node = *i;
        if (!visited[node.getV()])
        {
            if (DFSUtil(node.getV(), visited, goal, cost + node.getWeight()))
            {
                cout << node.getV() << " " ;
                return true;
            }
        }
    }

    return false;
}



void Graph::DFS(int v, int goal)
{
    bool *visited = new bool[V];
    for (int i = 0; i < V; i++)
        visited[i] = false;

    int cost = 0;
    DFSUtil(v, visited, goal, cost);

}

这是main()函数,我试图解析输入文件中的所有值:

int main()
{

    string line; // read every line into this variable
    int argCount = 0; // keep track of 4 arguments (V, start, goal, and
                      // J)
    int V, start, goal, J; // V is number of nodes, start is the start
                           // node, goal is goal node, J is just a
                           // number (ignore for now)

    //input for nodes, start, goal, and J
    while (getline(cin, line) && argCount < 4)
    {
        if (line[0] == '|') // reject the line and continue if the line
           continue;        // starts with '|'

        // convert the line which is a string into int and store in
        // respective variables
        switch (argCount)
        {
        case 0: V = stoi(line);
            argCount++;
            break;

        case 1: start = stoi(line);
            argCount++;
            break;

        case 2: goal = stoi(line);
            argCount++;
            break;
        case 3: J = stoi(line);
            argCount++;
            break;
        }

    }


    Graph g(V); // create a Graph of 'V' nodes or vertices.

    //ignore lines starting with '|'
    while (getline(cin, line))
    {
        if (line[0] == '|')
            continue;
        break;
    }
    // after the above loop, line contains the first row of the matrix

    // buffer array for taking in weight from stringstream.
    char weight[100];


    //parse first row of the matrix
    stringstream ss;
    ss << line;
    for (int v = 0; v < V; v++)
    {
        ss.getline(weight, 6, ' '); // get the value into weight,
                                    // ' '(whitespace) is a delimiter.
        if (weight[0] != '*')       // ignore if weight is '*'
            g.addEdge(0, v, weight);// call addEdge() to add edge
                                    // between 0 (because this is the
                                    // first row) and v and assign
                                    // weight.
    }
    ss << "";      // reset stringstream.
    ss.clear();   


    // parse rest of the rows of the matrix. first row already parsed
    // above
    for (int u = 1; u < V; u++) // u is row, starting from 1.
    {   getline(cin, line); // take the whole line
        ss.clear();
        ss.str("");
        ss << line;  // put the line in stringstream
        int v = 0;   // v is column number.
        while (ss >> weight)
        {
            if (weight[0] != '*')
                g.addEdge(u, v, weight); // add Edge between u and v.
            v++;  // increment column number.
        }
    }

    //ignore lines starting with '|' else set the h value for the nodes
    // THIS IS WHERE I AM STUCK. I NEED TO TAKE IN THE H VALUES AND   
    // ASSOCIATE THEM WITH THEIR NODES WHICH ARE ALREADY CREATED.

    int n = 0;
    list<AdjListNode>::iterator i;
    while (getline(cin, line))
    {   
        //cout << line;
        if (line[0] == '|') 
            continue;

        int h = stoi(line);
    }

    cout << "The adjacency list is : " << endl;
    g.printList();
    g.DFS(start, goal);
    cout << endl;

    return 0;
}

如何获取h值并将它们与正确的节点相关联?我很困惑,因为我在调用addEdge()函数之前在接收h值之前添加节点之间的边。我试图使用getter和setter但我无法实现这些概念因为我是新手。

谢谢!

编辑1 :添加了评论。

编辑2 :类结构应该是这样的:

对于邻接列表节点类,AdjListNode:

每个节点有3个属性;一个整数v来识别它,一个用于计算到达该节点的成本的权重,以及一个启发式值h,我对如何分配感到困惑,因为我已经调用了构造函数,并且稍后将从输入文件中解析h值

我知道我在这里缺少一些基本概念。

对于类Graph:

列表将所有AdjListNode类型节点存储为邻接列表。我需要对此进行A *搜索。

1 个答案:

答案 0 :(得分:0)

编辑:你的困难的核心在你的班级结构中找到。考虑一下你的目标 - 你想把h与边缘联系起来,对吗? &#34;关联&#34;意味着您需要在类中使用某种数据结构,这样才能实现这一目标。

有一些结构可供选择:元组和结构是两种可能性。如果将结构存储在列表中,则可以输入所有边,然后单步执行并输入所有h值。

另一种可能性是使用联合允许您将两种类型的值存储在同一列表中。这将更加困难,但可能会实现您的目标。

除此之外,你需要在这里自己做研究。

-

我知道你是新来的,所以我会告诉你,很少有人会直接给你正确的代码,特别是在这个复杂的事情上。只是一个抬头。

其次,如果您不了解自己的对象结构,那么您将处于相当不稳定的状态。我自己很难读书,而且我是一名专业人士。请为了对所有数字事物的喜爱,评论您的代码!你的各种单字母或双字母变量是什么意思......或者名字较长但仍然难以辨认的变量是什么意思? (不要觉得这太糟糕了......程序员的共同习惯。在这里问问任何人。)

吸气剂和制定者不是一件复杂的事情。 Getters只返回类中私有变量的值。 setter是一个接受参数的函数,并且通常在检查错误之后将该参数分配给类中的特定私有变量。

我现在能给你的最好建议是A)评论你的代码,B)弄清楚你的代码的基本对象结构。字面上写(在纸上,如果你必须)你的对象的名称,存储在其中的内容,隐藏的内容和公共内容,以及他们应该做什么。如果你弄明白了,你可能会自己找到答案。否则,请使用该信息编辑您的问题。

如果我看到了这项工作 - 目标类结构和一些好的评论 - 我将编辑更多有关如何修复代码的详细信息。这是关于自己做步法的。

顺便说一句,您的标题中的变量高于您的范围声明(在本例中为public:),这是一个禁忌。