学校要选择一个地方作为超市的位置,学校每个有K个部门,每个部门去超市的频率不一样,要求在可以设置的地点中选择一个最优的地点
来源:互联网 发布:网络信息发布平台 编辑:程序博客网 时间:2024/05/01 17:22
来源于一次课程设计,课设源码位置:https://github.com/treeandgrass/Algorithm-Course-Design
2.7.1题目描述
学校要选择一个地方作为超市的位置,学校每个有K个部门,每个部门去超市的频率不一样,要求在可以设置的地点中选择一个最优的地点。
1)设计核心算法,计算出超市可选位置和最优位置
2)已图像化界面的方式显示学校超市可选点和最优位置,显示学校超市和部门之间的路径和距离。
2.7.2程序使用说明
Java version:1.8.0_111
IDE:eclipse
直接编译Graph.java,然后运行即可
2.7.3简要分析和设计
算法步骤可以分为如下:
1)将部门和超市之间的通路转化为矩阵的形式,在程序中使用二维数组的形式表示,例如将部门和商店作为节点,然后可以把整个问题抽象成一个加权无向图的问题,A表示图中每个顶点之间的通路。A(i,j)表示点i,j之间的距离
2)使用floyd方法计算超市节点到每个部门之间的最短距离
3)在步骤2)的基础上计算每个超市到所有部门的花费。
Floyd算法伪代码:
输入:权重矩阵W[1...n,1...n],权重为每两个点之间的距离
输出:每两个点之间的最短距离矩阵D[1...n,1...n]
Floyd(W[1...n,1...n])
D<—W
For k<—1 to n do
For i <—1 to n do
For j <— 1 to n do
D[i,j]=min( D(i,j),D[i,k]+D[k,j] )
Return D
计算超市到各个部门之间的距离使用加法模型。设所有超市的点为P=(p1,p2,...,pk)
所有部门点为S=(s1,s2,....,sn),超市pk到所有部门的代价为Cost(pk),部门到超市的频率为F[1..k,1....n],F(k,i)表示部门i到超市k的频率,则可以得到如下计算式:
由上述不走计算出了各个商店到部门之间的距离。使用Floyd方法计算的过程中同时记录下了每两个点之间路径的中间点。然后再图像界面上画出整个图,在将超市和部门之间的路径用红色标识。并且在超市标识旁标识出相应大代价。
2.7.4测试用例
权重矩阵W:{{0,4,7,5,12},{4,0,5,6,9},
{7,5,0,-1,10},{5,6,-1,0,9},
{12,9,10,9,0}}
超市和部门名字数组:{"办公区1","超市选址1","超市选址2","办公区2","办公区3"}
超市和部门对应坐标:
{{50,50},{200,100},{80,400},{300,30},{400,300}}
超市ID,在{1,2},部门ID{0,3,4}
结果:
2.7.5源代码
package four.three;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 无向图
* @author ym
*
*/
public class Graph extends JPanel{
/**
* 序列号
*/
private static final long serialVersionUID = 1L;
//记录图中各店之间通路的权重值,存在通路权重值为正,否则为负
private int[][] w = null;
//记录超市的Id
private int[] market = null;
//记录单位Id
private int[] office=null;
//记录地点名字
String[] nameList = null;
//记录超市位置
int[][] position=null;
//记录单位去超市的频度
private int[] freq = null;
//记录个点之间的最短距离
private int[][] res = null;
//存储超市选点对应花费
HashMap<Integer,Integer> dotCostMap = null;
//记录各店之间的中间点
@SuppressWarnings("rawtypes")
private ArrayList[][] listMatrix = null;
//存储按照花费由小到大的排列的点
ArrayList<Integer> orderDots = null;
public Graph(int[][] w,int[] market,int[] office,int[] freq,String[] nameList,int[][] position){
this.w=w;
this.market=market;
this.office=office;
this.freq=freq;
this.nameList=nameList;
this.position=position;
this.res=new int[w.length][w[0].length];
this.listMatrix = new ArrayList[w.length][w[0].length];
dotCostMap = new HashMap<Integer,Integer>();
//计算可选点
orderDots = OptionalDot();
}
/**
* 使用Floyd算法计算超市和
* 单位之间的最短距离
*/
@SuppressWarnings("unchecked")
public void floyd(){
//初始化结果值
for(int i=0;i<res.length;i++){
for(int j=0;j<res[i].length;j++){
res[i][j]=w[i][j];
}
}
//Floyd 方法
for(int k=0;k<w.length;k++){
for(int i=0;i<w.length;i++){
for(int j=0;j<w[0].length;j++){
//同一点结束本次计算
if(i==j){
continue;
}
//存储两点间的点
listMatrix[i][j]=new ArrayList<Integer>();
int tempResult = -1;
if(res[i][k]>0&&res[k][j]>0){
tempResult = res[i][k]+res[k][j];
}
//计算K为i j中间点的情况
if(tempResult>0){
if(res[i][j]<0||(tempResult<res[i][j]&&res[i][j]>0)){
res[i][j]=tempResult;
//将i k的中间点加入到集合
if(listMatrix[i][k]!=null){
ArrayList<Integer> temp = listMatrix[i][k];
for(Integer value:temp){
listMatrix[i][j].add(value);
}
}
//将 k j的中间点加入到集合
if(listMatrix[k][j]!=null){
ArrayList<Integer> temp = listMatrix[k][j];
for(Integer value:temp){
listMatrix[i][j].add(value);
}
}
//加入中间点K
listMatrix[i][j].add(k);
}
}
}
}
}
}
/**
* 获取优先顺序后的超市可选点
* @return
*/
public ArrayList<Integer> OptionalDot(){
//调用Floyd方法计算超市和单位之间的最短距离
floyd();
//存储按照花费由小到大的排列的点
ArrayList<Integer> dots = new ArrayList<Integer>();
//使用插入排序
for(int i=0;i<market.length;i++){
//记录点
int cost=0;
//计算超市对应花费
for(int k=0;k<office.length;k++){
cost+=res[market[i]][office[k]]*freq[k];
}
//加入点和花费的映射
dotCostMap.put(market[i],cost);
//加入
dots.add(market[i]);
for(int j=dots.size()-1;j>0;j--){
//记录要比较的两个超市Id
int MID1 = dots.get(j);
int MID2 = dots.get(j-1);
if(dotCostMap.get(MID1)<dotCostMap.get(MID2)){
int temp = dots.get(j);
dots.set(j, dots.get(i));
dots.set(j-1,temp);
}
}
}
return dots;
}
@SuppressWarnings("unchecked")
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//画超市点
for(int i=0;i<market.length;i++){
//X坐标
int X = position[market[i]][0];
//Y坐标
int Y = position[market[i]][1];
//获得这个点的名字
String name=nameList[market[i]];
//获取超市到所有点的花费
String cost = "Cost:"+dotCostMap.get(market[i]);
g.fillOval(X-8, Y-8,16,16);
g.drawString(name, X-16,Y-16);
g.drawString(cost, X, Y+20);
}
//画超市点
for(int i=0;i<office.length;i++){
//X坐标
int X = position[office[i]][0];
//Y坐标
int Y = position[office[i]][1];
//获得这个点的名字
String name=nameList[office[i]];
g.fillOval(X-8, Y-8,16,16);
g.drawString(name, X-16,Y-16);
}
//对图中的各点连线
for(int i=0;i<w.length;i++){
for(int j=0;j<w[0].length;j++){
//同一点停止此次操作
if(i==j){
continue;
}
if(w[i][j]>0){
//获取两点的坐标
int IX = position[i][0];
int IY = position[i][1];
int JX = position[j][0];
int JY =position[j][1];
//路径权重
int weight=w[i][j];
g.drawLine(IX, IY, JX, JY);
//标出线段的权重
g.drawString(""+weight,(IX+JX)/2,(IY+JY)/2);
}
}
}
//设置线为红色
g.setColor(Color.RED);
//将超市到各个办公地区的点描红
for(int i=0;i<orderDots.size();i++){
for(int j=0;j<office.length;j++){
//获取i j两点间的路径
ArrayList<Integer> path = listMatrix[orderDots.get(i)][office[j]];
//路径的起始点
int start = orderDots.get(i);
//路径的终止点
int end=office[j];
for(int middle:path){
//获取两点的坐标
int startX = position[start][0];
int startY = position[start][1];
int middleX=position[middle][0];
int middleY=position[middle][1];
//描线
g.drawLine(startX,startY,middleX,middleY);
//更新开始点
start = middle;
}
int startX =position[start][0];
int startY =position[start][1];
int endX=position[end][0];
int endY = position[end][1];
//描绘路径中与结束点的连线
g.drawLine(startX,startY,endX,endY);
}
}
}
public int[][] getW() {
return w;
}
public void setW(int[][] w) {
this.w = w;
}
public int[] getMarket() {
return market;
}
public void setMarket(int[] market) {
this.market = market;
}
public int[] getOffice() {
return office;
}
public void setOffice(int[] office) {
this.office = office;
}
public int[] getFreq() {
return freq;
}
public void setFreq(int[] freq) {
this.freq = freq;
}
public int[][] getRes() {
return res;
}
public void setRes(int[][] res) {
this.res = res;
}
@SuppressWarnings("rawtypes")
public ArrayList[][] getListMatrix() {
return listMatrix;
}
@SuppressWarnings("rawtypes")
public void setListMatrix(ArrayList[][] listMatrix) {
this.listMatrix = listMatrix;
}
public HashMap<Integer, Integer> getDotCostMap() {
return dotCostMap;
}
public void setDotCostMap(HashMap<Integer, Integer> dotCostMap) {
this.dotCostMap = dotCostMap;
}
public static void main(String[] args) {
//权重值
int[][] w={{0,4,7,5,12},{4,0,5,6,9},
{7,5,0,-1,10},{5,6,-1,0,9},
{12,9,10,9,0}};
String[] nameList = {"办公区1","超市选址1","超市选址2","办公区2","办公区3"};
//对应坐标
int[][] position = {{50,50},{200,100},{80,400},{300,30},{400,300}};
//超市Id
int[] market = {1,2};
//单位Id
int[] office={0,3,4};
//频度
int[] freq = {4,7,11};
Graph graph = new Graph(w, market, office, freq,nameList,position);
//记录超市Id
// ArrayList<Integer> dots =graph.OptionalDot();
JFrame JF = new JFrame("学校超市选址问题");
JF.setSize(600,600);
JF.setLocationRelativeTo(null);
JF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JF.add(graph);
JF.setVisible(true);
/*for(Integer value:dots){
System.out.println("点:"+value+" 花费:"+graph.getDotCostMap().get(value));
}
for(int i=0;i<market.length;i++){
for(int j=0;j<office.length;j++){
System.out.println(market[i]+"与"+office[j]+"点间路径:");
//获取i j间的路径
ArrayList<Integer> path = graph.getListMatrix()[market[i]][office[j]];
for(int k:path){
System.out.print(" "+k);
}
}
}*/
}
}
- 学校要选择一个地方作为超市的位置,学校每个有K个部门,每个部门去超市的频率不一样,要求在可以设置的地点中选择一个最优的地点
- MySQL查询每个部门的最高薪水
- 查询每个部门最低工资的雇员信息
- 查询每个部门最低工资的雇员信息
- 一句sql 在所有部门中选择平均工资最高的部门所有员工
- 查询每个部门中薪资最高的员工
- SAP培训学校的选择
- 表单流程中一个节点是多人共同执行,每个执行人可以选择下一步要执行人员的实现思路
- 用一个SQL语句选出每个部门工资最高的员工
- 已知每个部门有一个经理,统计输出部门名称、部门总人数、 总工资和部门经理。
- 2006年15所中国一流大学 --每个学校的特色学科不一样
- 新浪微博 陈利人 面试题 给定k个数组,每个数组有k个整数。每个数组中选取一个整数,一共k个整数,取其和,一共可以得到k^k个和。给出方法,求得这k^k个和中,最小的k个。
- 大专时学的是计算机应用专业 想在北京报自考 也考软件专业的 可以选择那些学校?都有那些专业可以选择
- 每个cpu都有一个16K的中断栈
- 一个简单的超市开发文档
- shell, 文字游戏,在一个文本文件中查找出每个单词的使用频率并排序
- 数据库表,3个字段,姓名,薪水,部门,用一条sql语句求每个部门薪水最高的人姓名
- ROW_NUMBER() OVER函数的基本用法(根据部门分组,显示每个部门的工资等级)
- LitePal学习笔记
- elasticsearch 第二篇(配置篇)
- 图像数据预处理
- request的set-getParameter及getAttribute
- 基础练习 十六进制转八进制
- 学校要选择一个地方作为超市的位置,学校每个有K个部门,每个部门去超市的频率不一样,要求在可以设置的地点中选择一个最优的地点
- 百练2790:迷宫
- maven常用命令
- POJ 2632-Crashing Robots(模拟-robot移动)
- 郁闷的出纳员 treap模板
- A - 棋盘问题
- elasticsearch 第一篇(入门篇)
- 充值流量话费对接微信和支付宝支付实现
- 【从一开始】我的安卓学习之路(一)