多岔道口问题原理不想细解释,之前看到个大佬的详细解答很好先放上他的链接(我在一般的要求上增加了个特殊功能,使道路口和单向路不局限于5个)

​​​​​​(15条消息) 数据结构课设:多叉路口交通灯管理问题_此心安处是吾乡^_^的博客-CSDN博客

前置内容:动态二维数组要先申请指针的一维数组,再为指针new一个数组。

我这边主要讲一下新增内容的设计思路:

首先使如果有n个路口,它们之间的联通关系(如从A到B)构成了n^2个节点(这里包含从A到A这样的,会在之后删去),我们会发现一件事,如果将这些节点依次排序,它们的序号w和出入路口间(m,k)的关系是这样的:w=n*(m-1)+k,据此我们就能得节点次序和实际意义的关系,并借此推算两个节点之间是否能同时通行。

ps:上述公式有个bug不知大家发现没有,就是k=n时,如果用除和取余得到实际意义会出错,所以在通过次序推出实际意义时要加一个检测函数

然后呢我们来看如何判断从m道口到道口n的“指挥”和从i到k的“指挥”是否相冲突:

两个通行路线相冲突也就代表着它俩的路线相交,而车辆的行驶路线又是两个道口之间越近,它们的凹凸度就越小(也就是说路线与路线之间都是尽可能相互躲避的不会出现图中情况)

1. 我们给每一个道路口设置两个点,chu和ru,顾名思义,chu就是指这个点是车辆道口出去的位置,ru是车辆进入这一道口的位置,并依次标号1,2,3...,2*w

2. 在这种“避让”条件下两条路线相交,实质上就是它们的直线段要相交(如下图),也就是说我们只需要看两条直线段的出入点是否相对(就是出现图中的情况,一个线段之间的之间的联系被另一边“截断”)

因此,我们判断相应的邻接矩阵的某点是1还是0的方法就转化为了判断这样的两种路线出入点间是否冲突的问题了(如下面的代码,这里将一些不需要的点置为2,方便填充邻接矩阵)(还顺手将部分不包含的通行方式关掉,方便之后应用)

int qidian1 = -1, zhongdian1 = -1,qidian2=-1,zhongdian2=-1,max1=-1,max2=-1,min1=-1,min2=-1;for (int i=0;i<w;i++){//n*(h-1)+m=k+1  第h个路口向第m个跑if (((i+1)/n+1 )==((i+1)%n) || (i + 1) == w)//检测是否是自己向自己跑的情况,若是,则将fangshi中相应节点qiyong置为false并将相应矩阵置0{a[i].qiyong = false;for (int k = 0;k < w;k++){chujvzhen[i][k] = 2;}continue;}//n*(h-1)+m=i+1  第h个路口向第m个跑,并在之后转化为图形中线段是否相交的问题(可能要在实验报告中解释,画不出图)qidian1 = (i + 1) / n + 1;zhongdian1 = (i + 1) % n;if (zhongdian1 == 0){qidian1 =(qidian1-1)*2 - 1;zhongdian1=n;zhongdian1 = zhongdian1 * 2;}else{qidian1 = qidian1 * 2 - 1;zhongdian1 = zhongdian1 * 2 ;}max1 = qidian1 > zhongdian1 ? qidian1 : zhongdian1;min1= qidian1 < zhongdian1 ? qidian1 : zhongdian1;for (int k = 0;k < w;k++){if (((k + 1) / n + 1) == ((k + 1) % n )||(k+1)==w)//检测是否是自己向自己跑的情况,防止意外产生(把矩阵值设为2){chujvzhen[i][k] = 2;continue;}qidian2 = (k + 1) / n + 1;zhongdian2 = (k + 1) % n;if (zhongdian2 == 0){qidian2 = (qidian2 - 1) * 2 - 1;zhongdian2 = n;zhongdian2 = zhongdian2 * 2;}else{qidian2 = qidian2 * 2 - 1;zhongdian2 = zhongdian2 * 2;}max2 = qidian2 > zhongdian2 ? qidian2 : zhongdian2;min2 = qidian2 < zhongdian2 ? qidian2 : zhongdian2;if (((min2 < min1)  && ((max2 < max1) && (max2 > min1))) || ((max2 > max1) && ((min2 > min1) && (min2 < max1)))){chujvzhen[i][k] = 1;}else {chujvzhen[i][k] = 0;}}}

这样我们就得到了一个初步的矩阵,之后就是对它删删改改进行修补(其实就是根据只入不出和只出不入”删掉“部分行/列,并关闭节点)

//将只入不出和只出不入的找出来,相应道口变成2;记录消去了多少行/列for (int i = 0;b[i] != 0;i++){for (int k = 0;k < n;k++){int xiao = k * n + b[i]-1;a[xiao].qiyong = false;for (int h = 0;h < w;h++){chujvzhen[xiao][h] = 2;chujvzhen[h][xiao] = 2;}}}for (int i = 0;c[i] != 0;i++){for (int k = 0;k < n;k++){int xiao =(c[i]-1)*n+k;a[xiao].qiyong = false;for (int h = 0;h < w;h++){chujvzhen[xiao][h] = 2;chujvzhen[h][xiao] = 2;}}}shanchu(a, w);

这样的话我们就已经得到了一个零阶矩阵的模型(尽管里面还有些值为2的“被删除点”)

接下来我们就能正式制作邻接矩阵了!

检测矩阵相应位点的值是否为2,为2则跳过,不为2则录入,并依据值是否为1为相应的点增加频度

int s = 0, t = 0;int oo = (n * n - (rushu + chushu) * (n - 1) + rushu * chushu - n);//进行检测,0/1录入,2跳过for (int i = 0;i < w;i++){for (int k = 0;k < w;k++){if (chujvzhen[i][k] == 2){continue;}else{d[s][t] = chujvzhen[i][k];if (chujvzhen[i][k] == 1){a[s].pindu++;a[t].pindu++;}t++;if (t == oo){s++;t = 0;continue;}}}}

这样我们的邻接矩阵和节点的内容就基本制作内容就完成了,可以根据课本/大佬给出的方法规划道路了(下附完整代码)

本人能力有限,还懒,有些可以优化的地方没有改,大家要是有意见直接说就成

#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
struct fangshi {int ru;int chu;//尽管能通过数组的次序来计算,但为了方便使用和后续排序问题用了churuint cixv;//方便在涂色中进行初始化(int pindu=0;//方便排序int color=0;bool qiyong=true;
};//记录出入的方式以及冲突数void shanchu(fangshi *a,int n)//删除道路节点中不需要的项
{int mount=n-1;for (int i = 0,k=0;k< n;k++){if (a[i].qiyong == false&&a[i].ru!=0){for (int k = i;k < n-1;k++){a[k] = a[k + 1];}a[mount].pindu = 0;a[mount--].ru = 0;}if (a[i].qiyong != false){i++;}}for (int i = 0;i < n;i++){a[i].cixv = i;}
}void zhizuoshuzu(int n, int b[]/*只能出*/, int c[]/*只能入*/, int**d,fangshi*a,int rushu,int chushu)//将输入的数据转化为临界矩阵方便后续进行计算
{int w = n*n;//计算有多少个通行方式(默认无单项情况,且包含从A向A的情况,这些问题都将在后续部分删除)int** chujvzhen = new int* [w];for (int i = 0; i < w; i++) {chujvzhen[i] = new int[w];a[i].ru = (i + 1) / n + 1;a[i].chu = (i + 1) % n;if ((i + 1) % n == 0){a[i].ru--;a[i].chu=n;}a[i].cixv = i;}//创建一个关于某两种通行方式是否可以同时开始的邻接矩阵,并将通行方式的节点初始化int qidian1 = -1, zhongdian1 = -1,qidian2=-1,zhongdian2=-1,max1=-1,max2=-1,min1=-1,min2=-1;for (int i=0;i<w;i++){//n*(h-1)+m=k+1  第h个路口向第m个跑if (((i+1)/n+1 )==((i+1)%n) || (i + 1) == w)//检测是否是自己向自己跑的情况,若是,则将fangshi中相应节点qiyong置为false并将相应矩阵置0{a[i].qiyong = false;for (int k = 0;k < w;k++){chujvzhen[i][k] = 2;}continue;}//n*(h-1)+m=i+1  第h个路口向第m个跑,并在之后转化为图形中线段是否相交的问题(可能要在实验报告中解释,画不出图)qidian1 = (i + 1) / n + 1;zhongdian1 = (i + 1) % n;if (zhongdian1 == 0){qidian1 =(qidian1-1)*2 - 1;zhongdian1=n;zhongdian1 = zhongdian1 * 2;}else{qidian1 = qidian1 * 2 - 1;zhongdian1 = zhongdian1 * 2 ;}max1 = qidian1 > zhongdian1 ? qidian1 : zhongdian1;min1= qidian1 < zhongdian1 ? qidian1 : zhongdian1;for (int k = 0;k < w;k++){if (((k + 1) / n + 1) == ((k + 1) % n )||(k+1)==w)//检测是否是自己向自己跑的情况,防止意外产生(把矩阵值设为2){chujvzhen[i][k] = 2;continue;}qidian2 = (k + 1) / n + 1;zhongdian2 = (k + 1) % n;if (zhongdian2 == 0){qidian2 = (qidian2 - 1) * 2 - 1;zhongdian2 = n;zhongdian2 = zhongdian2 * 2;}else{qidian2 = qidian2 * 2 - 1;zhongdian2 = zhongdian2 * 2;}max2 = qidian2 > zhongdian2 ? qidian2 : zhongdian2;min2 = qidian2 < zhongdian2 ? qidian2 : zhongdian2;if (((min2 < min1)  && ((max2 < max1) && (max2 > min1))) || ((max2 > max1) && ((min2 > min1) && (min2 < max1)))){chujvzhen[i][k] = 1;}else {chujvzhen[i][k] = 0;}}}//将只入不出和只出不入的找出来,相应道口变成2;记录消去了多少行/列for (int i = 0;b[i] != 0;i++){for (int k = 0;k < n;k++){int xiao = k * n + b[i]-1;a[xiao].qiyong = false;for (int h = 0;h < w;h++){chujvzhen[xiao][h] = 2;chujvzhen[h][xiao] = 2;}}}for (int i = 0;c[i] != 0;i++){for (int k = 0;k < n;k++){int xiao =(c[i]-1)*n+k;a[xiao].qiyong = false;for (int h = 0;h < w;h++){chujvzhen[xiao][h] = 2;chujvzhen[h][xiao] = 2;}}}shanchu(a, w);int s = 0, t = 0;int oo = (n * n - (rushu + chushu) * (n - 1) + rushu * chushu - n);//进行检测,0/1录入,2跳过for (int i = 0;i < w;i++){for (int k = 0;k < w;k++){if (chujvzhen[i][k] == 2){continue;}else{d[s][t] = chujvzhen[i][k];if (chujvzhen[i][k] == 1){a[s].pindu++;a[t].pindu++;}t++;if (t == oo){s++;t = 0;continue;}}}}for(int i = 0;i < oo;i++){d[i][i] = 1;a[i].pindu++;}for (int i = 0; i < w; i++){delete[]chujvzhen[i];chujvzhen[i] = NULL;}delete[]chujvzhen;chujvzhen = NULL;
}void maopaopaixv(fangshi*a,int n)//冒泡排序
{for (int i = 0;i < n;i++) {for (int j = n-1;j > i;j--) {if (a[j].pindu > a[j - 1].pindu) {int degree = a[j - 1].pindu;int index = a[j - 1].cixv;int ru=a[j-1].ru,chu=a[j-1].chu;bool  qiyong=a[j-1].qiyong;a[j - 1].pindu = a[j].pindu;a[j - 1].cixv = a[j].cixv;a[j - 1].ru = a[j].ru;a[j - 1].chu = a[j].chu;a[j - 1].qiyong = a[j].qiyong;a[j].pindu = degree;a[j].cixv = index;a[j].ru = ru;a[j].chu = chu;a[j].qiyong = qiyong;}}}
}bool shangse(fangshi *a, int** d, int color, int j,int n) //检测j能否上color的“颜色”
{if (a[j].color != 0)return false;for (int i = 0;i < n&&a[i].ru!=0;i++)if (d[a[j].cixv][i] == 1){for (int m = 0;m < n && a[m].ru != 0;m++){if (a[m].cixv == i){if (a[m].color == color){return false;}}}}return true;
}int main()
{int h,** d=NULL,chushu=0,rushu=0;cout << "输入道路数" << endl;cin >> h;int* b = new int[h];int* c = new int[h];cout << "输入只能出的路口数,输入0截止" << endl;int n = 0;do{cin >> n;b[chushu] = n;if(n !=0)chushu++;} while (n != 0);cout << "输入只能入的路口数,输入0截止" << endl;do{cin >> n;c[rushu] = n;if (n != 0)rushu++;} while (n != 0);int zeze = h * h - (rushu + chushu) * (h - 1)+rushu*chushu - h;d = new int* [zeze];for (int i = 0; i <zeze; i++) {d[i] = new int[zeze]();}fangshi* daolu = new fangshi[h*h];zhizuoshuzu(h, b, c, d,daolu,rushu,chushu);maopaopaixv(daolu, h * h);int k = 0;while (1) {k++;int i;for (i = 0;i < h*h&&daolu[i].ru!=0;i++)if (daolu[i].color == 0) {daolu[i].color = k;break;}if (i == h*h||daolu[i].ru==0)break;for (int j = 0;j < h * h && daolu[j].ru != 0;j++)if (shangse(daolu, d, k, j, h * h)){daolu[j].color = k;}}cout << "一下是一种满足要求(“涂色最少”)的交通灯考虑,一次完整的行驶共有" <<--k<< "段行驶(颜色),具体情况如下:" << endl;for (int i=1;k> 0;k--){cout << "第" << i++ << "段行驶:";for (int o = 0;(o < h * h) && (daolu[o].ru != 0);o++){if (daolu[o].color == k){cout << "从第" << daolu[o].ru << "路口向第" << daolu[o].chu << "路口 ";}}cout << endl;}delete[]b;b = NULL;delete[]c;c = NULL;delete[]d;d = NULL;delete[] daolu;daolu = NULL;return 0;
}

多叉路口交通灯问题,输入任意道口数输出排序解决方案相关推荐

  1. ACMNO.18 C语言-选择排序 用选择法对10个整数从小到大排序。 输入 10个整数 输出 排序好的10个整数

    题目描述 用选择法对10个整数从小到大排序. 输入 10个整数 输出 排序好的10个整数 样例输入 4 85 3 234 45 345 345 122 30 12 样例输出 3 4 12 30 45 ...

  2. 输出第三个单词c语言,基础c语言问题:要求输入任意单词,输出单词的每个字母后的第三个字母。例如输入yeah,则输出bhdk...

    满意答案 badsmiling 2014.05.09 采纳率:52%    等级:9 已帮助:614人 #include #include #define MAX_LENGTH 20 int main ...

  3. eda交通灯控制器波形输入_基于VHDL的交通灯控制器设计

    应用VHDL语言设计数字系统,大部分设计工作可在计算机上完成,从而缩短系统开发时间,提高工作效率.下面介绍基于VHDL设计交通灯控制器的一种方案,并给出源程序和仿真结果. 1 系统功能与要求 交通灯控 ...

  4. CASE_01 基于FPGA的交通灯控制器

        该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源. 目录 1 案例引导 1.1 硬件设计初窥 1.2 逻辑设计初窥 2 模块级逻 ...

  5. 微型计算机技术 论文,微型计算机技术课程设计论文报告微机交通灯控制系统_毕业论文.docx...

    * * *计算机科学系 课程设计(综合实验)报告 (2014--2015 年度第一学期) 课程名称:微型计算机技术 题 目:微机交通灯控制系统 班 级: 学 号: 学生姓名: 指导教师: 设计周数: ...

  6. 通行时间可调的两路口交通灯设计实验(基于Multisim仿真)

    一.设计要求简述: 东西方向的红.黄.绿灯和南北方向的红.黄.绿灯按照正常的工作时序进行工作,黄灯亮时应为闪烁状态. 通行时间和黄灯闪亮时间可以在0-99秒内任意设定. 十字路口要有数字显示作为时间提 ...

  7. 「雕爷学编程」Arduino动手做(34)——三色LED交通灯模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  8. 计算机控制系统课程设计交通灯,太原理工大学数字逻辑课设(交通灯)

    <太原理工大学数字逻辑课设(交通灯)>由会员分享,可在线阅读,更多相关<太原理工大学数字逻辑课设(交通灯)(25页珍藏版)>请在人人文库网上搜索. 1.太原理工大学计算机科学与 ...

  9. 交通灯定时控制系统的设计

    目        录 一.  内容摘要-----------------1 二.  设计内容及要求--------------1 三.  总设计原理----------------1 四.  单元电路 ...

最新文章

  1. springmvc常见问题汇总
  2. 在loadrunner中使用winsocket协议编写脚步三部曲
  3. Jeremy Keith在 Fronteers 2010 上的主题演讲
  4. 教你用java统计目录下所有文档的词频
  5. boost::neighbor_bfs_visitor用法的测试程序
  6. 在oracle下我们如何正确的执行数据库恢复
  7. 收集一些实用的电脑使用习惯和操作技巧
  8. 【IEnumerable】扩展方法的使用 C#
  9. Flutter LayoutBuilder 用来获取父布局的尺寸大小
  10. Arthas实践--快速排查Spring Boot应用404/401问题
  11. Moddable SDK为物联网开发提供JavaScript引擎:不到32KB
  12. ISP PIPLINE (六) AWB
  13. python中pop类型_Python基础之基本数据类型
  14. 惊 腾讯云、阿里云服务器无需备案配置域名访问方法
  15. 解决谷歌浏览器chrome的CPU占用率过高的问题
  16. 拍照爱摆“剪刀手”?呵呵,1.5米内100%还原指纹
  17. 游戏开发、安卓、IOS知识概括
  18. 随手查_python
  19. Excel 中的一些计数及求和的函数
  20. 测试用例 --- 注册163邮箱密码

热门文章

  1. 自然语言处理——词性标注、词干提取、词形还原
  2. 如何在ubuntu终端输入密码显示星号
  3. [知识库分享系列] 二、.NET(ASP.NET)
  4. 黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第四章 使用SCAPY掌控网络(2)Scapy实现ARP缓存投毒
  5. java中实现方法重试机制
  6. 雅虎黑客事件严重 Verizon表示可能放弃收购
  7. SCU 2818 QQ音速
  8. 医用设备心跳心率检测mp3文件输出(mp3文件处理)(二)
  9. VScode检测到#include 错误,请更新includepath。已为此翻译单元 禁用波形曲线//gcc : 无法将“gcc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
  10. Java + OpenCV 对图像进行水平投影和竖直投影