首页 行业资讯 宠物日常 宠物养护 宠物健康 宠物故事

求关键路径的程序(最好是C#的,其他的也可以)

发布网友 发布时间:2022-04-22 04:30

我来回答

5个回答

热心网友 时间:2023-06-23 13:26

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Toppath
{
    class Program
    {
        static void Main(string[] args)
        {
            node<char>[] Mynode ={new node<char>('A'),new node<char>('B'),new node<char>('C'),
                                  new node<char>('D'),new node<char>('E'),new node<char>('F'),
                                  new node<char>('G'),new node<char>('H'),new node<char>('I'),
                                  new node<char>('J')};
            GraphAdjlist<char> xiong = new GraphAdjlist<char>(Mynode);
            xiong.SetEdge(Mynode[0], Mynode[1], 3);
            xiong.SetEdge(Mynode[0], Mynode[2], 4);
            xiong.SetEdge(Mynode[1], Mynode[3], 5);
            xiong.SetEdge(Mynode[1], Mynode[4], 6);
            xiong.SetEdge(Mynode[2], Mynode[3], 8);
            xiong.SetEdge(Mynode[2], Mynode[5], 7);
            xiong.SetEdge(Mynode[3], Mynode[4], 3);
            xiong.SetEdge(Mynode[4], Mynode[7], 4);
            xiong.SetEdge(Mynode[4], Mynode[6], 9);
            xiong.SetEdge(Mynode[5], Mynode[7], 6);
            xiong.SetEdge(Mynode[7], Mynode[8], 5);
            xiong.SetEdge(Mynode[6], Mynode[9], 2);
            xiong.SetEdge(Mynode[8], Mynode[9], 3);
            xiong.toppath();
            Console.ReadKey();
        }
    }
    class node<T>
    {
        public T Data
        { get; set; }
        public node(T temp)
        {
            Data = temp;
        }
    }
    class vextable<T>
    {
        public node<T> Vex
        { get; set; }
        public adjlistnode<T> First
        { get; set; }
        public int In
        { get; set; }
        public vextable()
        {
            Vex = null;
            First = null;
        }
        public vextable(node<T> p)
        {
            Vex = p;
            First = null;
            In = 0;
        }
    }

    class adjlistnode<T>
    {
        public int Index
        { get; set; }
        public adjlistnode<T> next
        { get; set; }
        public int Weight
        { get; set; }
        public adjlistnode(int index)
        {
            Index = index;
            next = null;
            Weight = 0;
        }
        public adjlistnode()
        {
            Index = -1;
            next = null;
            Weight = 0;
        }
    }
    class GraphAdjlist<T>
    {
        public vextable<T>[] vext
        { get; set; }
        public int[] Visited
        { get; set; }
        public vextable<T> this[int index]
        {
            get { return vext[index]; }
            set { vext[index] = value; }
        }
        public GraphAdjlist(node<T>[] mynode)
        {
            vext = new vextable<T>[mynode.Length];
            Visited = new int[mynode.Length];
            for (int i = 0; i < mynode.Length; i++)
            {
                vext[i] = new vextable<T>(mynode[i]);
            }
        }
       
        public int Indexofvertex(node<T> x)
        {
            for (int i = 0; i < vext.Length; i++)
            {
                if (vext[i].Vex.Equals(x))
                    return i;
            }
            Console.WriteLine("no this node");
            return -1;
        }

        public void SetEdge(node<T> v1, node<T> v2, int v)//这个Top排序要使用的是一个有向邻接表才对
        {
            int iv1 = Indexofvertex(v1);
            int iv2 = Indexofvertex(v2);
            adjlistnode<T> p1 = new adjlistnode<T>(iv1);
            adjlistnode<T> p2 = new adjlistnode<T>(iv2);
            //在v1处添加v2;
            p2.next = vext[iv1].First;
            vext[iv1].First = p2;
            p2.Weight = v;
            vext[iv2].In++;//添加入度          
        }
        public void toppath()
        {
            Stack<int> temp = new Stack<int>();//用什么都行,但必须保持一致用于存放拓扑坐标
            Stack<int> toparray = new Stack<int>();//用stack最好,因为正向过去算etv,反向回来算ltv,先入后出最好
            Stack<int> path = new Stack<int>();//再反一次,存的就是正常的拓扑图,从头开始那种
            int p = -1; int m = -1; 
            adjlistnode<T> q = new adjlistnode<T>();
            int[] etv = new int[vext.Length];//最早点
            int[] ltv = new int[vext.Length];//最晚点
            int ete = -1;//最早边,是判断变量不是数组用来找边的
            int lte = -1;//最晚边
            int k = 0;
            for (int i = 0; i < vext.Length; i++)
            {
                if (vext[i].In == 0)
                {
                    temp.Push(i);//压入序号
                }
            }
            while (toparray.Count != vext.Length)
            {
                p = temp.Pop();
                toparray.Push(p);
                q = vext[p].First;
                while (q != null)
                {
                    vext[q.Index].In--;//下标就用最原始的值,顺序用栈保存好就行
                    if (vext[q.Index].In == 0)
                    {
                        temp.Push(q.Index);
                    }
                    if (etv[p] + q.Weight > etv[q.Index])//正向过去算etv,etv均初始化为0
                    {
                        etv[q.Index] = etv[p] + q.Weight;
                    }
                    q = q.next;
                }
            }//栈就是用来压和弹的,如果想取完还有,那就在找个栈,边取边存,不是给你拿来遍历用的                      
            for (int i = 0; i < vext.Length; i++)//找到etv的最大值拿来赋值给ltv因为这是反向回去,最大值是终点值
            {
                if (etv[i] > m)
                {
                    m = etv[i];
                }
            }

            while (toparray.Count != 0)
            {
                k = toparray.Pop();//由于是栈所以弹出的肯定是终点
                path.Push(k);//再保存一次
                q = vext[k].First;
                ltv[k] = m;//将所有最晚顶点置成最大值
                while (q != null)
                {
                    if ((ltv[q.Index] - q.Weight) < ltv[k])//算ltv其实是min
                    {
                        ltv[k] = ltv[q.Index] - q.Weight;
                    }
                    q = q.next;
                }
            }
            while (path.Count != 0)//这边我感觉还是按拓扑顺序得好,因为这样可以有序的排列顶点,不按也成反正是找边,边构成路
            {
                int i = path.Pop();
                q = vext[i].First;
                while (q != null)
                {
                    ete = etv[i];//边上的值,其实看etv和etl就能看到,只不过用这种方式更加形象的定位到边,并且给出权值
                    lte = ltv[q.Index] - q.Weight;
                    if (ete == lte)
                    {
                        Console.WriteLine(vext[i].Vex.Data + "" + vext[q.Index].Vex.Data + "" + q.Weight);
                    }
                    q = q.next;
                }               
            }       
            Console.ReadKey();
        }
    }
}
朋友看得懂不,不懂可以加我QQ:10333209,也许你已成为大神,就当一起学习吧

样图在上,结果在下,路径加weight值,刚好学到这里,刚好只会C#,刚好找到你这贴,分享快乐

热心网友 时间:2023-06-23 13:27

我帮你查了 没查到 呵呵 不好意思了 朋友!

热心网友 时间:2023-06-23 13:27

//获取新的 Process 组件并将其与当前活动的进程关联的主模块的完整路径,包含文件名(进程名)。
string str = System.Diagnostics.Process.GetCurrentProcess().MainMole.FileName;
result: X:\xxx\xxx\xxx.exe (.exe文件所在的目录+.exe文件名)
//获取和设置当前目录(即该进程从中启动的目录)的完全限定路径。
string str = System.Environment.CurrentDirectory;
result: X:\xxx\xxx (.exe文件所在的目录)

//获取当前 Thread 的当前应用程序域的基目录,它由程序集冲突解决程序用来探测程序集。
string str = System.AppDomain.CurrentDomain.BaseDirectory;
result: X:\xxx\xxx\ (.exe文件所在的目录+”\”)

//获取和设置包含该应用程序的目录的名称。
string str = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
result: X:\xxx\xxx\ (.exe文件所在的目录+”\”)

//获取启动了应用程序的可执行文件的路径,不包括可执行文件的名称。
string str = System.Windows.Forms.Application.StartupPath;
result: X:\xxx\xxx (.exe文件所在的目录)

//获取启动了应用程序的可执行文件的路径,包括可执行文件的名称。
string str = System.Windows.Forms.Application.ExecutablePath;
result: X:\xxx\xxx\xxx.exe (.exe文件所在的目录+.exe文件名)

//获取应用程序的当前工作目录(不可靠)。
string str = System.IO.Directory.GetCurrentDirectory();
result: X:\xxx\xxx (.exe文件所在的目录)

热心网友 时间:2023-06-23 13:28

具体是什么要求

热心网友 时间:2023-06-23 13:28

你说的是什么关键路径?
最短路吗?还是网络流?

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com