直接上题目
1、 有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi 。如果选择了活动i,则它在半开时间区间[si, fi]内占用资源。若区间[si, fi]与区间[sj, fj]不相交,则称活动i与活动j是相容的。也就是说,当si≥fj或sj≥fi时,活动i与活动j相容。活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子。该问题要求高效地安排一系列争用某一公共资源的活动。贪心算法提供了一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。
题目解析:
怎么样选择活动才能让一天之内举办的活动数最多呢?答案是优先选择结束时间早的活动。
上代码喽!
package 贪心算法;
/*
* i 0 1 2 3 4 5 6 7 8 9
* si
* fi
*/
import java.util.*;
import java.io.*;
public class ActivityPlan {
static int n = 11;
static int[] i = new int[n];
static int[] si = new int[n];
static int[] fi = new int[n];
static String str1 = "";
static String str2 = "";
static String str3 = "";
static String strResult = "";
static ArrayList<Integer> al = new ArrayList<Integer>();
public static void main(String[] args) {
// TODO Auto-generated method stub
//getMyNum();
getRandomNum();
System.out.println("未排序的随机数如下");
printNum();
sortNum();
System.out.println("排序后的随机数如下");
printNum();
getPlan();
printAL();
writeData();
}
//手动输入
public static void getMyNum(){
int[] s = {1,3,0,5,3,5,6,8,8,12,2};
int[] f = {4,5,6,7,8,9,10,11,12,14,13};
si = s;
fi = f;
}
//得到活动的随机开始时间与结束时间
public static void getRandomNum(){
for(int i = 0;i < n;i++){
si[i] = (int)(Math.random()*(23-0)+1);
fi[i] = (int)(Math.random()*(24-si[i])+si[i]+1);
}
}
//输出活动的开始时间与结束时间
public static void printNum(){
System.out.print("i : ");
str1 = str1 + "i : ";
for(int i = 0; i < n; i ++){
if(i>9){
System.out.print(i+" ");
str1 = str1 + i+" ";
}else{
System.out.print(i+" ");
str1 = str1 + i+" ";
}
}
System.out.println();
System.out.print("si : ");
str2 = str2 + "si : ";
for(int i = 0 ;i < n;i++){
if(si[i]>9){
System.out.print(si[i]+" ");
str2 = str2 + si[i]+" ";
}else{
System.out.print(si[i]+" ");
str2 = str2 + si[i]+" ";
}
}
System.out.println();
System.out.print("fi : ");
str3 = str3 + "fi : ";
for(int i = 0 ;i < n;i++){
if(fi[i]>9){
System.out.print(fi[i]+" ");
str3 = str3 + fi[i]+" ";
}else{
System.out.print(fi[i]+" ");
str3 = str3 + fi[i]+" ";
}
}
str1 = str1+" ";
str2 = str2+" ";
str3 = str3+" ";
System.out.println();
}
//将随机数排序
public static void sortNum(){
for(int i = 0; i < n;i++){
for(int j = i+1; j< n;j++){
if(fi[i]>fi[j]){
int swap = 0;
swap = fi[i];
fi[i] = fi[j];
fi[j] = swap;
swap = si[i];
si[i] = si[j];
si[j] = swap;
}
}
}
}
//计算最优结果
public static void getPlan(){
if(al.isEmpty()){
al.add(0);
}
int num = 0;
for(int i = 0; i < n-1;i++){
for(int j = i+1;j<n;j++){
System.out.print(num++);
if(fi[i]<=si[j]){
al.add(j);
i = j;
}
}
}
System.out.println();
num = 0;
for(int i = 1 ; i < n;i++){
int x = al.get(al.size()-1);
System.out.print(num++);
if(fi[x]<=si[i]){
System.out.println(fi[x]+" "+si[i]);
al.add(i);
}
}
}
//输出结果集合
public static void printAL(){
System.out.println();
strResult = strResult+"最多可以办"+al.size()+"个活动,活动序号如下: ";
for(int i = 0 ;i < al.size();i++){
strResult = strResult+al.get(i)+" ";
}
System.out.println(strResult);
}
//数据写入文件
public static void writeData(){
FileWriter fw =null;
BufferedWriter bfw = null;
String filename = "ActivityPlan.txt";
File file = new File(filename);
if(file.exists()){
if(file.delete()){
System.out.println();
System.out.println("文件已经删除");
}
}
if(!file.exists()){
try {
file.createNewFile();
System.out.println("文件已经创建");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
fw = new FileWriter(filename);
bfw = new BufferedWriter(fw);
bfw.append(str1);
bfw.append("\r\n");
bfw.append(str2);
bfw.append("\r\n");
bfw.append(str3);
bfw.append("\r\n");
bfw.append(strResult);
bfw.append("\r\n");
} catch (Exception e2) {
// TODO: handle exception
System.out.println("写入文件出错");
}finally{
try {
bfw.close();
fw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
System.out.println("写入文件成功");
}
//此方法仅供参考
public static void getMyPlan(){
if(al.isEmpty()){
al.add(0);
}
for(int i = 0; i < n-1;i++){
for(int j = i+1;j<n;j++){
if(fi[i]<=si[j]){
al.add(j);
i = j;
}
}
}
}
}
2、 小数背包问题:给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?背包问题:与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
题目解析:
如何装包会使得包的价值最大?优先装单位价值高的物品。
上代码喽!
package 贪心算法;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
public class BagPlan {
static int n = 5;
static double C = 10;
static double[] Wi = new double[n];
static double[] Vi = new double[n];
static String str1 = "";
static String str2 = "";
static String str3 = "";
static String strResult = "";
public static void main(String[] args) {
// TODO Auto-generated method stub
//getMyNum();
getRandomNum();
System.out.println("未排序的随机数如下");
printNum();
sortNum();
System.out.println("排序后的随机数如下");
printNum();
getPlan();
writeData();
}
private static void getMyNum() {
// TODO Auto-generated method stub
double[] s = {1,2,3};
double[] f = {30,50,60};
Wi = s;
Vi = f;
}
private static void getRandomNum() {
// TODO Auto-generated method stub
for(int i = 0;i < n;i++){
Wi[i] = (int)(Math.random()*10+1);
Vi[i] = (int)(Math.random()*50+20);
}
}
private static void sortNum() {
// TODO Auto-generated method stub
for(int i = 0; i < n;i++){
for(int j = i+1; j< n;j++){
double wv1 = Vi[i]/Wi[i];
double wv2 = Vi[j]/Wi[j];
if(wv1<wv2){
double swap = 0;
swap = Wi[i];
Wi[i] = Wi[j];
Wi[j] = swap;
swap = Vi[i];
Vi[i] = Vi[j];
Vi[j] = swap;
}
}
}
}
private static void printNum() {
// TODO Auto-generated method stub
System.out.print("i : ");
str1 = str1 + "i : ";
for(int i = 1; i <= n; i ++){
if(i>9){
System.out.print(i+" ");
str1 = str1 + i+" ";
}else{
System.out.print(i+" ");
str1 = str1 + i+" ";
}
}
System.out.println();
System.out.print("Wi : ");
str2 = str2 + "Wi : ";
for(int i = 0 ;i < n;i++){
if(Wi[i]>9){
System.out.print(Wi[i]+" ");
str2 = str2 + Wi[i]+" ";
}else{
System.out.print(Wi[i]+" ");
str2 = str2 + Wi[i]+" ";
}
}
System.out.println();
System.out.print("Vi : ");
str3 = str3 + "Vi : ";
for(int i = 0 ;i < n;i++){
if(Vi[i]>9){
System.out.print(Vi[i]+" ");
str3 = str3 + Vi[i]+" ";
}else{
System.out.print(Vi[i]+" ");
str3 = str3 + Vi[i]+" ";
}
}
str1 = str1+" ";
str2 = str2+" ";
str3 = str3+" ";
System.out.println();
}
private static void getPlan() {
// TODO Auto-generated method stub
int i = 0;
double MyBag = 0;
double sumValue = 0;
for(;i<n;i++){
if((C-MyBag)>=Wi[i]){
MyBag = MyBag + Wi[i];
sumValue = sumValue+Vi[i];
}else{
break;
}
}
if(i<n){
double w = Wi[i];
double v = Vi[i];
sumValue = sumValue+(C-MyBag)*(Vi[i]/Wi[i]);
}
System.out.println();
strResult = "最多能装到包里物品的价值为:"+sumValue;
System.out.println(strResult);
}
private static void writeData() {
// TODO Auto-generated method stub
FileWriter fw =null;
BufferedWriter bfw = null;
String filename = "C:/Users/LB101514/Desktop/Documents/java/BagPlan.txt";
File file = new File(filename);
if(file.exists()){
if(file.delete()){
System.out.println();
System.out.println("文件已经删除");
}
}
if(!file.exists()){
try {
file.createNewFile();
System.out.println("文件已经创建");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
fw = new FileWriter(filename);
bfw = new BufferedWriter(fw);
bfw.append(str1);
bfw.append("\r\n");
bfw.append(str2);
bfw.append("\r\n");
bfw.append(str3);
bfw.append("\r\n");
bfw.append(strResult);
bfw.append("\r\n");
} catch (Exception e2) {
// TODO: handle exception
System.out.println("写入文件出错");
}finally{
try {
bfw.close();
fw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
System.out.println("写入文件成功");
}
private static void getMyPlan() {
// TODO Auto-generated method stub
int i = 0;
double MyBag = 0;
double sumValue = 0;
for(;i<n;i++){
if((C-MyBag)>=Wi[i]){
MyBag = MyBag + Wi[i];
sumValue = sumValue+Vi[i];
}else{
break;
}
}
if(i<n){
double w = Wi[i];
double v = Vi[i];
sumValue = sumValue+(C-MyBag)*(Vi[i]/Wi[i]);
}
System.out.println();
strResult = "最多能装到包里物品的价值为:"+sumValue;
System.out.println(strResult);
}
}