sika0819 2017-08-16 11:09 采纳率: 0%
浏览 1239

c#有向图判断公边环路问题

最近做一个模拟电路串并联的程序,卡在了环路检测上。
目前基于深度检测dfs算法判断环路的,但是这种算法在两个环路公用一条回路的情况下发生了错误。
图片说明
图片说明
附代码:
public class DirectedCycle
{ // 判断图是否有环

    private bool[] inStack;
    private List<Stack<Vertex>> cycleList;//电流环
    private List<Stack<int>> cycleList2;//普通环
    private int[] edgeTo;
    private bool[] isMarked;

    public DirectedCycle(DiGraph g)
    {
        inStack = new bool[g.getVetx()];
        edgeTo = new int[g.getVetx()];
        cycleList =new List<Stack<Vertex>>();
        cycleList2 = new List<Stack<int>>();
        isMarked = new bool[g.getVetx()];
        for (int i = 0; i < g.getVetx(); i++)
        {
            if (!isMarked[i])
            {
                dfs(g, i);
            }
        }
    }
    public DirectedCycle(EdgeWeightDiGraph g)
    {
        inStack = new bool[g.getV()];
        edgeTo = new int[g.getV()];
        isMarked = new bool[g.getV()];
        cycleList = new List<Stack<Vertex>>();
        for (int i = 0; i < g.getV(); i++)
        {
            if (!isMarked[i])
            {
                dfs(g, i);
            }
        }
    }

    private void dfs(EdgeWeightDiGraph g, int begin)
    {
        isMarked[begin] = true;
        inStack[begin] = true;
        foreach (DirectedEdge e in g.getAdj(begin))
        {
            int node = e.getTo();
            //if (hasCycle()) return;

            if (!isMarked[node])
            {
                edgeTo[node] = begin;
                dfs(g, node);
            }
            else if (inStack[node])
            { // 如果当前路径Stack中含有node,又再次访问的话,说明有环  
              // 将环保存下来  
                Stack<Vertex> cycle = new Stack<Vertex>();
                for (int i = begin; i != node; i = edgeTo[i])
                {
                    cycle.Push(g.getVetrx(i));
                    Console.Write("访问环点:" + i + " ");
                }
                cycle.Push(g.getVetrx(node));
                Console.Write("访问环点:" + node + " ");
                //   cycle.Push(g.getVetrx(begin));

                cycleList.Add(cycle);
            }
        }
        inStack[begin] = false;
    }
    private void dfs(DiGraph g, int begin)
    {
        isMarked[begin] = true;
        inStack[begin] = true;
        for (int node=0; node<g.getAdj(begin).Count;node++)
        {
           // if (hasCycle()) return;
            int nodeValue = g.getAdj(begin)[node];
            if (!isMarked[nodeValue])
            {
                edgeTo[nodeValue] = begin;
                dfs(g, nodeValue);
            }
            else if (inStack[nodeValue])
            { // 如果当前路径Stack中含有node,又再次访问的话,说明有环  
              // 将环保存下来  
                Stack<int> cycle = new Stack<int>();
                for (int i = begin; i != nodeValue; i = edgeTo[i])
                {
                    cycle.Push(i);
                }
                cycle.Push(nodeValue);
                //cycle.Push(begin);
                cycleList2.Add(cycle);
            }
        }
        inStack[begin] = false;
    }

    public bool hasCycle()
    {
        return cycleList!=null;
    }

    public List<Stack<int>> getCycle()
    {//返回普通环
        return cycleList2;
    }
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("有"+cycleList.Count+"个环,分别为:\n");
        for (int i = 0; i < cycleList.Count; i++)
        {
            for (int j = 0; j < cycleList[i].Count; j++)
            {
                sb.Append(cycleList[i].ElementAt(j).i + "————>");
            }
            sb.Append("\n");
        }

        return sb.ToString();
    }
    /// <summary>
    /// 设计思路:
    /// 找出所有连接电池的环
    /// </summary>
    /// <param name="g"></param>
    /// <param name="battery"></param>
    public void Generation(EdgeWeightDiGraph g, Vertex battery)
    {//计算电路,为了方便直接给出电池在哪.为了方便暂定电池只有一个
        if (CheckLinked(battery)) {
            Voltage = battery.Voltage;//电池的电压为总电压
            if (cycleList.Count == 1)
            {//串联
                Console.Write("电路为串联");
                for (int i = 0; i < cycleList[0].Count-1; i++)
                {
                    AllResistance += cycleList[0].ElementAt(i).Resistance;
                }
                if (AllResistance == 0)
                {
                    Console.WriteLine("短路了");
                    return;
                } 
                Eletry = Voltage / AllResistance;
                SetEle(g, cycleList[0], Eletry);
                Console.WriteLine("总电阻为:"+AllResistance);
            }
            else {
                Console.Write("并联,算法测试中……可能有bug");
                for (int i = 0; i < cycleList.Count; i++)
                {

                }
            }
        }
    }
    public void SetEle(EdgeWeightDiGraph g,Stack<Vertex> cycle,float electry) {//每圈分别设置电压,电流
        for (int c = 0; c < cycle.Count-1; c++)
        {
            for (int i = 0; i < g.getV(); i++) {
                if (g.getVetrx(i) == cycle.ElementAt(c)) {
                    g.getVetrx(i).Electricity = electry;
                    if (g.getVetrx(i).Resistance != 0)//不是电线或者电池的情况下计算电压。
                    {
                        g.getVetrx(i).Voltage = electry * g.getVetrx(i).Resistance;
                    }
                    Console.WriteLine("发电中,元器件"+i+"电流为:"+electry+"电压为:"+ g.getVetrx(i).Voltage);
                    for (int j = 0; j < g.getVetrx(i).adj.Count; j++)
                    {
                        g.getVetrx(i).adj[j].Electricity = electry;

                    }
                }
        }
        }
    }
    bool CheckLinked(Vertex battery)
    {//检测断路
        if (cycleList.Count > 0) { 
            for (int i = 0; i < cycleList.Count; i++)
            {
                if (CheckBattery(cycleList[i],battery))
                    return true;
            }
        }
        Console.WriteLine("断路!请链接电池!");
        return false;
    }
    bool CheckBattery(Stack<Vertex> ring,Vertex battery) {
        return ring.Contains(battery);
    }

    public float AllResistance;//总电阻
    public float Voltage;//总电压
    public float Eletry;//总电流
}

}


  • 写回答

1条回答 默认 最新

  • threenewbee 2017-08-16 15:44
    关注
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog