Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何确定节点在图形数据结构中是否有多个输入?_Java_Graph - Fatal编程技术网

Java 如何确定节点在图形数据结构中是否有多个输入?

Java 如何确定节点在图形数据结构中是否有多个输入?,java,graph,Java,Graph,我正在尝试创建一个简单的字符串调制网络。 想法是网络的输出是最后执行的模块的输出。 模块可以以任何方式排列,如果模块必须将连接作为输入,则应将输入相加(字符串串联) 为了实现它,我考虑将网络表示为一个图形数据结构 现在阻碍我的是如何确定模块有两个连接作为输入(这样我就能够在将结果作为输入输入之前对两个输出求和) 使用什么算法遍历图形?广度优先 有更好的解决方案来代表网络吗? [非常感谢伪代码]如果您将图形存储为邻接列表(“此节点指向这些节点”),那么您可以简单地迭代邻接列表,并将A->B对交换

我正在尝试创建一个简单的字符串调制网络。

想法是网络的输出是最后执行的模块的输出。
模块可以以任何方式排列,如果模块必须将连接作为输入,则应将输入相加(字符串串联)

为了实现它,我考虑将网络表示为一个图形数据结构

现在阻碍我的是如何确定模块有两个连接作为输入(这样我就能够在将结果作为输入输入之前对两个输出求和)

使用什么算法遍历图形?广度优先

有更好的解决方案来代表网络吗?
[非常感谢伪代码]

如果您将图形存储为邻接列表(“此节点指向这些节点”),那么您可以简单地迭代邻接列表,并将A->B对交换为B->A,创建反向邻接列表(“这些节点指向此节点”)

更多信息请访问

编辑:

从图表中,邻接列表将是:

A -> [B, C]
B -> [D]
C -> [D]
D -> []
这可以表示为
映射
。编写一个方法,获取一对并更新映射,称之为
connect
。要构建结构,您可以使用
connect(A,B)
connect(A,C)
connect(B,D)
connect(C,D)
来调用它


若要反转,请创建一个新贴图以保持反转的结构。迭代映射中的每个键,然后遍历列表中的每个值,并在反转结构上调用
connect
,参数反转。

您可以在广度优先和深度优先两种方式中实现这一点。我将发布一个深度优先算法:

public class Node {

    private List<Node> parents = new ArrayList<Node>();
    private List<Node> children = new ArrayList<Node>();
    private Map<Node, String> receivedMessages = new HashMap<Node, String>();
    private String id = "";

    public Node(String id) {
        this.id = id;
    }

    void processMessage(Node sender, String message) {
        if (parents.contains(sender))
            receivedMessages.put(sender, message);

        // if all the parents sent the message
        if (receivedMessages.size() == parents.size()) {
            String newMessage = composeNewMessage(receivedMessages);

            if (children.size() == 0) // if end node or "leaf"
                ouputResult(this, newMessage);
            else {
                for (Node child : children) {
                    child.processMessage(this, newMessage);
                }
            }
        }
    }

    public void addParent(Node parent) {
        if (parent != null)
            parents.add(parent);
        parent.children.add(this);
    }

    public void addChild(Node child) {
        if (child != null)
            children.add(child);
        child.parents.add(this);
    }

    private void ouputResult(Node node, String newMessage) {
        // TODO: implement
    }

    private String composeNewMessage(Map<Node, String> receivedMessages2) {
        // TODO: implement
        return "";
    }

    public static void main(String[] args) {
        Node A = new Node("A");
        Node B = new Node("B");
        Node C = new Node("C");
        Node D = new Node("D");
        Node start = new Node("start");
        Node end = new Node("end");
        A.addParent(start);
        B.addParent(A);
        C.addParent(A);
        D.addParent(B);
        D.addParent(C);
        end.addParent(D);
        A.processMessage(start, "Message");
    }
}
公共类节点{
private List parents=new ArrayList();
private List children=new ArrayList();
private Map receivedMessages=new HashMap();
私有字符串id=“”;
公共节点(字符串id){
this.id=id;
}
void processMessage(节点发送方、字符串消息){
if(父项包含(发送方))
receivedMessages.put(发送方,消息);
//如果所有的父母都发了这个消息
if(receivedMessages.size()==parents.size()){
字符串newMessage=composeNewMessage(receivedMessages);
if(children.size()==0)//if结束节点或“叶”
输出结果(此,新消息);
否则{
用于(节点子节点:子节点){
processMessage(this,newMessage);
}
}
}
}
公共void addParent(节点父节点){
如果(父项!=null)
parents.add(parent);
parent.children.add(此);
}
公共void addChild(节点子节点){
if(child!=null)
添加(child);
child.parents.add(此);
}
私有void ouputResult(节点节点,字符串newMessage){
//TODO:实现
}
私有字符串组合消息(映射接收消息2){
//TODO:实现
返回“”;
}
公共静态void main(字符串[]args){
节点A=新节点(“A”);
节点B=新节点(“B”);
节点C=新节点(“C”);
节点D=新节点(“D”);
节点开始=新节点(“开始”);
节点结束=新节点(“结束”);
A.addParent(开始);
B.父母(A);
C.父母(A);
D.父母(B);
D.父母(C);
完.添加父项(D);;
A.processMessage(开始,“消息”);
}
}

我认为,如果在两个方向上遍历图形,则应使用输入和输出对其进行双向建模。事实上,当您的默认情况是向后跟踪导入引用时,您可以只使用这些引用,然后完全删除输入->输出引用。抱歉,我没有这样做。这是我原来的邻接列表:[[AB->C->D][BD][CD]]。什么是反向邻接列表?得到反向列表后,该怎么办?使用什么样的遍历算法?很抱歉,这个概念对我来说有点复杂……结果是[a->[],B->[a],C->[a],D->[B,C]]。指向其输入的每个节点。A有一个节点,B和C有一个作为输入,D有2个,需要连接。是的。你认为我需要包括这个吗?我想这可能是显而易见的。也许不是。图(节点和边)是计算机科学中一个迷人的主题。它们适用于许多看似不同的主题。给他们一个阅读,有更多的魔术被发现!我想composeNewMessage()方法不需要参数,因为它可以访问receivedMessages实例变量。是。。当然你说你想要伪代码,我这样说是为了澄清(composeNewMessage使用receivedMessages)。如果代码质量对您来说是一致的,请删除它。我如何获得起始节点和结束节点?