`
datoplay
  • 浏览: 1614937 次
文章分类
社区版块
存档分类
最新评论

差分约束系统C++实现

 
阅读更多

差分约束:线性规划矩阵A的每一行包含一个1与一个-1,其他元素为0.因此,由Ax<=b给出的约束条件是m个差分约束集合,其中包含n个未知元。每个约束条件为不等式:

xj-xi<=bk

其中1<=i,j<=n,i<=k<=m

解决方法:把n个未知元看成n的有向图的顶点,xj-xi<=bk表示顶点j到顶点i长度为bk的有向线段。再添加一个v0顶点,与v0到其余顶点的有向线段,长度为0。(如下图)

可以证明 xi=β(v0,vi)(β(v0,vi)为顶点0到顶点i的最短路径长度)。所以就可以利用Bellman_Ford算求单源最短路径(不能用Dijkstra算法,因为有向线段长度可以为负)

// 差分约束系统.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream>
#define MAX 100
#define Infinity 65535
using namespace std;

//边的尾节点结构体
struct edgeNode
{
int no; //边尾端的序号
int weight; //边权值
struct edgeNode * next; //下一个
};

//节点结构体
struct vexNode
{
char info; //节点名称
struct edgeNode *link; //与之相连的端点
};

//存储节点信息
vexNode adjlist[MAX];
//前驱节点
int parent[MAX];
////源点到节点j最短路径的花费
int lowcost[MAX];
//差分矩阵
int a[MAX][MAX];
//约束集
int w[MAX];

//根据差分矩阵建立邻接表存储
//adjlist为节点集,parent[j]为从0节点到节点j的最短路径的前驱节点
//lowcost[j]为从0节点到节点j的最短路径的代价
//w为输入的差分约束
//m,n分别为差分矩阵的行数和列数
void createGraph(vexNode *adjlist,int *parent,int *lowcost,int *w,int m,int n)
{
int i,j;
//初始化,节点vi的名称为char(a+i)
for(i=0;i<=n;i++)
{
adjlist[i].info = (char)('a' + i);
adjlist[i].link = NULL;
lowcost[i] = Infinity;
parent[i] = i;
}
int col1,col2;
col1 = col2 = 0;
edgeNode *p1;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
if(a[i][j]==-1)
col1 = j;
else if(a[i][j]==1)
col2 = j;
}
p1 = (edgeNode*)malloc(sizeof(edgeNode));
p1->no = col2;
p1->weight = w[i];
p1->next = adjlist[col1].link;
adjlist[col1].link = p1;
}
for(i=1;i<=n;i++)
{
p1 = (edgeNode*)malloc(sizeof(edgeNode));
p1->no = i;
p1->weight = 0;
p1->next = adjlist[0].link;
adjlist[0].link = p1;
}
lowcost[0] = 0;
}

//寻找v0到,每一个节点的最短路径
bool Bellman_Ford(vexNode *adjlist,int *lowcost,int *parent,const int n)
{
int i,j;
for(j=0;j<n;j++)
{
for(i=0;i<=n;i++)
{
edgeNode *p1 = adjlist[i].link;
while(p1 != NULL)
{
if(lowcost[i]+p1->weight <lowcost[p1->no])
{
lowcost[p1->no] = lowcost[i]+p1->weight;
parent[p1->no] = i;
}
p1 = p1->next;
}
}
}
//检查有无负回路
for(i=1;i<=n;i++)
{
edgeNode *p2 = adjlist[i].link;
while(p2 != NULL)
{
if(lowcost[p2->no]>lowcost[i]+p2->weight)
return false;
p2 = p2->next;
}
}
return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
int cases;
cout<<"请输入案例的个数:";
cin>>cases;
while(cases--)
{
int i,j;
int n,m;
cout<<"请输入差分矩阵的行数(m)与列数(n):";
cin>>m>>n;
cout<<"请输入差分矩阵:"<<endl;
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
cout<<"请输入约束集:"<<endl;
for(i=1;i<=m;i++)
cin>>w[i];
//创建邻接表
createGraph(adjlist,parent,lowcost,w,m,n);
//输出邻接表
/*
for(i=0;i<=n;i++)
{
edgeNode *p = adjlist[i].link;
cout<<i<<":";
while(p != NULL)
{
cout<<"("<<p->no<<","<<p->weight<<") ";
p = p->next;
}
cout<<endl;
}
*/
//调用Bellman-Ford算法
bool flag = Bellman_Ford(adjlist,lowcost,parent,n);
if(!flag)
cout<<"无解"<<endl;
else
{
//输出解集
cout<<"其中一个解集为(此解集加上一个任意的常数d也是其解集):"<<endl;
for(i=1;i<=n;i++)
cout<<"x"<<i<<"="<<lowcost[i]<<endl;
}
}
system("pause");
return 0;
}

---------------------------------------------------程序测试---------------------------------------------------

请输入案例的个数:1
请输入差分矩阵的行数(m)与列数(n):8 5
请输入差分矩阵:
1 -1 0 0 0
1 0 0 0 -1
0 1 0 0 -1
-1 0 1 0 0
-1 0 0 1 0
0 0 -1 1 0
0 0 -1 0 1
0 0 0 -1 1
请输入约束集:
0 -1 1 5 4 -1 -3 -3
其中一个解集为(此解集加上一个任意的常数d也是其解集):
x1=-5
x2=-3
x3=0
x4=-1
x5=-4
请按任意键继续. . .

分享到:
评论

相关推荐

    差分约束系统 2024年1月6日

    差分约束系统 2024年1月6日

    基于差分进化算法的多用户OFDM自适应资源分配

    该算法首先在均等功率下进行子载波分配,然后通过添加约束条件检测改进步骤,改进差分进化算法,并采用该算法根据设置的兼顾用户公平性与系统容量的目标函数,全局寻优实现用户间的功率分配。仿真结果表明,算法在低...

    C++图论专题(form Alex_Wei

    最短路(Bellman-Ford,Dijsktra,SPFA,Johnson,Floyd),差分约束,最小生成树(Kruskal,Prim,Boruvka),有向图与无向图连通性(割点,割边,E-BCC 和 SCC 的缩点),欧拉回路。 适合刚接触C++,并对基础数据...

    非线性系统手册原书第5版混沌,分形,元胞自动机,遗传算法,基因表达式编程,支持向量机,小波,隐马尔可夫模型,模糊逻辑与C 、JAVA和SymbolicC 程序

    7.2.2 差分方程系统 7.3 时间延迟反馈控制 7.4 微小周期扰动 7.5 共振扰动和控制 第8章 混沌同步性 8.1 引言 8.2 混沌同步性 8.2.1 同步性控制 8.2.2 同步子系统 8.3 耦合发电机的同步性 8.4 相耦合系统 第9章 分形...

    最短路问题

    该PPT讲了求最短路算法SPFA,Bellman-Ford和Floyed-Warshall算法,还拓展了差分约束。十分适合初学者用

    DEePX:Epsilon的差分进化-分区转换(ePX)

    Epsilon的差分进化-分区转换(ePX) ***具有epsilon分区交叉(ePX)的标准差分演化*** 说明:这是带有ePX的DE的源代码,用于CEC17 Suite单目标优化的绑定约束优化功能。 参考:Tinos,R .; 惠特利D. Chicano,F....

    精通SQL 结构化查询语言详解

    10.2.2 IN子查询实现集合交和集合差运算 10.2.3 EXISTS子查询  10.2.4 EXISTS子查询实现两表交集  10.2.5 SOME/ALL子查询  10.2.6 UNIQUE子查询  10.3 相关子查询  10.3.1 使用IN引入相关子查询  ...

    精通SQL--结构化查询语言详解

    10.2.2 in子查询实现集合交和集合差运算 191 10.2.3 exists子查询 192 10.2.4 exists子查询实现两表交集 194 10.2.5 some/all子查询 195 10.2.6 unique子查询 197 10.3 相关子查询 198 10.3.1 使用in引入相关...

    基于 FLAC 和遗传算法的斜坡加固方案优化方法 (2011年)

    提 出一种以性价比为评价指标,运 用快速拉格朗日差分分析和遗传算法对斜坡加固方案进行优化的新方法。 应用 FLAC 计算斜坡加固前后的稳定性系数(Ks),以性价比(加固前后稳定性系数的差和工程造价的比)为目标函 数,以...

    IOI国家集训队论文集1999-2019

    + [差分约束系统](#差分约束系统) + [平面图](#平面图) + [2-SAT](#2-sat) + [最小生成树](#最小生成树) + [二分图](#二分图) + [Voronoi图](#voronoi图) + [偶图](#偶图) * [树](#树) + [树](#树-1) + ...

    C#微软培训资料

    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...

    ENigMA:具有强大的网格生成功能的多物理场框架

    该代码实现了一些数值方法,例如有限体积法(FVM),有限差分法(FDM),有限元方法(FEM),边界元方法(BEM),平滑粒子流体动力学(SPH)等,用于部分数值近似每个域中的微分方程(PDE)。 它还提供了用于生成...

    field_interpolation:使用有限元和稀疏线性最小二乘法进行fie​​ld_interpolation

    使用有限差分法进行场插值一种用于在一维或几维内插稀疏和/或有噪数据的方法。 可用于从点云生成带符号的距离场。代码结构该库位于field_interpolation/ 。 src/包含一个示例应用程序。描述介绍假设我们要近似一些...

    算法导论(part1)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

    算法导论(part2)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

Global site tag (gtag.js) - Google Analytics