Неожиданное поведение ссылок в графе узлов

Я пытаюсь создать алгоритм, который включает в себя создание графа узлов (и я не говорю о том, что алгоритм еще не завершен и не работает). Я получаю ввод из файла, а затем создаю новый узел в графе или настраиваю уже существующий, создавая новое соединение между узлами. Мой план состоял в том, что я мог добраться из любого узла в любой другой независимо от расстояния. Когда я редактирую поле "лампы", что-то идет не так, и один соседний узел видит, что еще есть какие-то лампы, что не соответствует действительности, потому что я только что сделал "connection.lamps -= removeLamps". В отладке я вижу, что это поле отличается в двух ссылках, но когда я пытаюсь сделать ReferenceEquals (закомментированный код), он просто везде печатает True. Я думал, что если я отредактирую ссылку, она будет применяться везде. Любая идея, почему это происходит?

      internal class Graph
{
    public List<Node> nodes = new List<Node>();
}

internal class Node
{
    public int number;
    public List<Connection> connections = new();
}

internal class Connection
{
    public Node nextNode;
    public int lamps;
}

internal class Lamps
{
    private Graph _graph;

    public void GetInput(StreamReader sr)
    {
        Graph graph = new Graph();

        int places_count = int.Parse(sr.ReadLine()); // places

        for (int placeIndex = 0; placeIndex < places_count - 1; placeIndex++)
        {
            var spl = sr.ReadLine().Split(' ');

            int input_from = int.Parse(spl[0]),       // there is from A
                input_to = int.Parse(spl[1]),         // to B
                input_lamps = int.Parse(spl[2]);      // C lamps

            Node fromNode, toNode;

            if (graph.nodes.Any(x => x.number == input_from))
            {
                fromNode = FindInGraphByNumber(graph, input_from);
            }
            else
            {
                fromNode = new Node();
                fromNode.number = input_from;
                graph.nodes.Add(fromNode);
            }

            if (graph.nodes.Any(x => x.number == input_to))
            {
                toNode = FindInGraphByNumber(graph, input_to);
            }
            else
            {
                toNode = new Node();
                toNode.number = input_to;
                graph.nodes.Add(toNode);
            }

            fromNode.connections.Add(new Connection() { nextNode = toNode, lamps = input_lamps });
            toNode.connections.Add(new Connection() { nextNode = fromNode, lamps = input_lamps });
        }

        //Console.WriteLine(Node.ReferenceEquals(graph.nodes.First(x => x.number == 3), graph.nodes.First(x => x.number == 1).connections.First(x => x.lamps == 3).nextNode));
        //Console.WriteLine(Node.ReferenceEquals(graph.nodes.First(x => x.number == 1), graph.nodes.First(x => x.number == 0).connections.First(x => x.lamps == 1).nextNode));
        //Console.WriteLine(Node.ReferenceEquals(graph.nodes.First(x => x.number == 0), graph.nodes.First(x => x.number == 2).connections.First(x => x.lamps == 2).nextNode));
        //Console.WriteLine(Node.ReferenceEquals(graph.nodes.First(x => x.number == 2), graph.nodes.First(x => x.number == 5).connections.First(x => x.lamps == 1).nextNode));
        //Console.WriteLine(Node.ReferenceEquals(graph.nodes.First(x => x.number == 2), graph.nodes.First(x => x.number == 4).connections.First(x => x.lamps == 1).nextNode));
        //Console.WriteLine(Node.ReferenceEquals(graph.nodes.First(x => x.number == 3), graph.nodes.First(x => x.number == 5).connections[0].nextNode.connections.First(x => x.lamps == 2).nextNode.connections.First(x => x.lamps == 1).nextNode.connections.First(x => x.lamps == 3).nextNode));

        _graph = graph;
    }

    private static Node FindInGraphByNumber(Graph graph, int number)
    {
        for (int graphNodeIndex = 0; graphNodeIndex < graph.nodes.Count; graphNodeIndex++)
        {
            if (graph.nodes[graphNodeIndex].number == number)
            {
                return graph.nodes[graphNodeIndex];
            }
        }

        throw new ArgumentException($"{nameof (number)} {number} does not exist in {nameof (graph)}.");
    }

    public int Proceed()
    {
        int counter = 0;

        while (_graph.nodes.Any(x => x.connections.Any(y => y.lamps > 0)))
        {
            for (int nodeIndex = 0; nodeIndex < _graph.nodes.Count; nodeIndex++)
            {
                var node = _graph.nodes[nodeIndex];

                // if there is no path with lamps above 0
                if (!node.connections.Any(x => x.lamps > 0))
                    continue;

                if (IsEdge(node.number))
                {
                    if (node.connections.Count(x => x.lamps > 0) != 1)
                        throw new UnreachableException("IsEdge should handle this.");

                    var edgeNode = node.connections.First(x => x.lamps > 0);
                    int removeLamps = edgeNode.lamps;
                    counter += removeLamps;
                    edgeNode.lamps = 0;

                    for (int connectedNodeIndex = 0; connectedNodeIndex < edgeNode.nextNode.connections.Count; connectedNodeIndex++)
                    {
                        // path from neighboring node
                        var connection = edgeNode.nextNode.connections[connectedNodeIndex];

                        // if lamps are not zero or less
                        if (connection.lamps <= 0)
                            continue;

                        connection.lamps -= removeLamps;
                    }
                }
            }
        }



        return counter;
    }

    private bool IsEdge(int number)
    {
        var connections = _graph.nodes.First(x => x.number == number).connections;
        return connections.Count(x => x.lamps > 0) == 1;
    }
}

0 ответов

Другие вопросы по тегам